搜索框实现各大搜索引擎智能提示功能(jsonp跨域实现自动补全搜索建议)

首先是各大搜索引擎的数据

谷歌/google:http://suggestqueries.google.com/complete/search?client=youtube&q=#content#&jsonp=window.google.ac.h
callback:window.google.ac.h
返回值:window.google.ac.h([“关键字”,[[“关键字规划师”,0],[“关键字研究工具”,0],[“关键字”,0],[“关键字 搜寻量”,0],[“关键字提取”,0],[“关键字参数”,0],[“关键字广告收费方式”,0],[“关键字广告是什么”,0],[“关键字 英文”,0],[“关键字驱动”,0]],{“k”:1,”q”:”5mIo50mwAhPfTuFojvpE9njU9Fc”}])

百度/baidu:http://suggestion.baidu.com/su?wd=#content#&cb=window.baidu.sug
callback:window.baidu.sug
返回值:window.baidu.sug({q:”关键字”,p:false,s:[“关键字优化”,”关键字是什么”,”c语言关键字”,”excel关键字排序”,”关键字和标识符区别”,”关键字优化_选择站优云”,”关键字优化_选择站优云丶”,”关键字优化_都赞站优云”,”关键字递增排序”,”关键字是关系中能够用来唯一标识元组的属性”]});

必应/bing:http://api.bing.com/qsonhs.aspx?type=cb&q=#content#&cb=window.bing.sug
callback:window.bing.sug
返回值:if(typeof window.bing.sug == ‘function’) window.bing.sug({“AS”:{“Query”:”关键字”,”FullResults”:1,”Results”:[{“Type”:”AS”,”Suggests”:[{“Txt”:”关键字点右边选项可分类搜索”,”Type”:”AS”,”Sk”:””,”HCS”:0},{“Txt”:”关键字驱动”,”Type”:”AS”,”Sk”:”AS1”},{“Txt”:”关键字提取”,”Type”:”AS”,”Sk”:”AS2”},{“Txt”:”关键字搜索的技巧”,”Type”:”AS”,”Sk”:”AS3”},{“Txt”:”关键字云图”,”Type”:”AS”,”Sk”:”AS4”},{“Txt”:”关键字屏蔽”,”Type”:”AS”,”Sk”:”AS5”},{“Txt”:”关键字supper的作用是”,”Type”:”AS”,”Sk”:”AS6”},{“Txt”:”关键字参数 python”,”Type”:”AS”,”Sk”:”AS7”}]}]}}/* pageview_candidate */);

好搜/so:https://sug.so.360.cn/suggest?encodein=utf-8&encodeout=utf-8&format=json&word=#content#&callback=window.so.sug
callback:window.so.sug
返回值:window.so.sug({“ext”:”nlpv=zzzc_0”,”query”:”关键字”,”result”:[{“rank”:”0.009386”,”resrc”:”0.287926”,”source”:”recall”,”word”:”关键字广告”},{“rank”:”0.008406”,”resrc”:”0.556381”,”source”:”recall”,”word”:”关键字查询”},{“rank”:”0.005110”,”resrc”:”0.380169”,”source”:”recall”,”word”:”关键字优化”},{“rank”:”0.001996”,”resrc”:”0.225187”,”source”:”recall”,”word”:”关键字工具”},{“rank”:”0.000570”,”resrc”:”0.363073”,”source”:”recall”,”word”:”关键字搜索引擎”},{“rank”:”0.000547”,”resrc”:”0.353710”,”source”:”recall”,”word”:”关键字排名”},{“rank”:”0.000395”,”resrc”:”0.283342”,”source”:”recall”,”word”:”关键字查询工具”},{“rank”:”0.000216”,”resrc”:”0.177443”,”source”:”recall”,”word”:”关键字优化技巧”},{“rank”:”0.000200”,”resrc”:”0.166434”,”source”:”recall”,”word”:”关键字搜索”},{“rank”:”0.000199”,”resrc”:”0.165665”,”source”:”recall”,”word”:”关键字加密工具”}],”ssid”:”1e9edd15637f4da5b6af8e06f722b255”,”version”:”personal”}
)

搜狗/sougou:https://www.sogou.com/suggnew/ajajjson?type=web&key=#content#
callback:window.sogou.sug
返回值:window.sogou.sug([“关键字”,[“关键字挖掘”,”关键字搜索”,”关键字 点击搜索进入”,”关键字是什么”,”关键字序列”,”关键字static的作用是什么”,”关键字 点右边选项可分类搜索”,”关键字排序”,”关键字驱动测试英文”,”关键字广告”],[“0;0;0;0”,”1;0;0;0”,”2;0;0;0”,”3;0;0;0”,”4;0;0;0”,”5;0;0;0”,”6;0;0;0”,”7;0;0;0”,”8;0;0;0”,”9;0;0;0”],[“”,””,””,””,””,””,””,””,””,””],[“0”],””,”suglabId_1”],-1);

为了方便使用我将搜索引擎数据放在一个数组对象中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
"engine": [{
"name": "谷歌",
"value": "google",
"href": "https://www.google.com/search?q=",
"sugurl": "http://suggestqueries.google.com/complete/search?client=youtube&q=#content#&jsonp=window.google.ac.h",
"icon": "./img/engineLogo/google.ico",
"show": true,
"select": ""
}, {
"name": "必应",
"value": "bing",
"href": "https://cn.bing.com/search?q=",
"sugurl": "http://api.bing.com/qsonhs.aspx?type=cb&q=#content#&cb=window.bing.sug",
"icon": "./img/engineLogo/bing.ico",
"show": true,
"select": "selected"
}, {
"name": "百度",
"value": "baidu",
"href": "https://www.baidu.com/s?wd=",
"sugurl": "http://suggestion.baidu.com/su?wd=#content#&cb=window.baidu.sug",
"icon": "./img/engineLogo/baidu.svg",
"show": true,
"select": ""
}, {
"name": "搜狗",
"value": "sougou",
"href": "https://www.sogou.com/web?query=",
"sugurl": "https://www.sogou.com/suggnew/ajajjson?type=web&key=#content#",
"icon": "./img/engineLogo/sougou.ico",
"show": true,
"select": ""
}]

JSONP是跨域访问的一种方式。由于服务器返回的JavaScript代码可以直接引用,通过回调函数的方式就可以间接的获取服务器的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// searchInput为获取的输入框
let searchInput = document.querySelector("#searchInput");
// 监听按键抬起
searchInput.onkeyup = () => {
// 获取选择的搜索引擎
let engineValue = selectEngine.childNodes[0].alt;
// 从数据源中找到选中的搜索引擎
// 如果没有多个搜索引擎切换可以忽略
let engine = jsonData.engine.find(item => item.value == engineValue);
// 将链接赋值给变量
let [href, sugurl] = [engine.href, engine.sugurl];
// 获取输入框的值
let value = searchInput.value;
// 如果输入框的值为空则清空列表并隐藏
if (value == "") {
searchList.innerHTML = "";
searchList.style.display = "none";
return;
}
// 替换链接中'#content#'为输入框的值
sugurl = sugurl.replace("#content#", value);
// 各个引擎的callback,由于各搜索引擎返回的数据不同需要做判断
// sugValue为定义的函数,用来接收获取到的数据
window.google = {
ac: {
h: function (json) {
sugValue(href, json[1])
}
}
}
window.bing = {
sug: function (json) {
sugValue(href, json.AS.Results[0].Suggests);
}
}
window.baidu = {
sug: function (json) {
sugValue(href, json.s)
}
}
window.sogou = {
sug: function (json) {
sugValue(href, json[1])
}
}
// 创建script标签
let script = document.createElement("script");
script.src = sugurl;
document.querySelector("head").appendChild(script);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 接收返回数据的函数
function sugValue(href, value) {
let sugList = "";
if (value.length == 0) {
return;
}
// 根据返回值判断渲染
value.forEach(item => {
if (typeof item == "string") {
sugList += `<li><a href="${href}${item}">${item}</a></li>`
} else if (typeof item == "object" && item.Txt !== undefined) {
sugList += `<li><a href="${href}${item.Txt}">${item.Txt}</a></li>`
} else {
sugList += `<li><a href="${href}${item[0]}">${item[0]}</a></li>`
}
})
searchList.innerHTML = sugList;
searchList.style.display = "block";
}

什么是跨域:

跨域是由浏览器同源策略引起的,是指页面请求的接口地址,必须与页面url地址处于同域上(即域名,端口,协议相同)。这是为了防止某域名下的接口被其他域名下的网页非法调用,是浏览器对JavaScript施加的安全限制。

前端解决跨域问题常用的解决方案:

  • JSONP:利用script标签可跨域的特点,在跨域脚本中可以直接回调当前脚本的函数。
  • CORS:服务器设置HTTP响应头中Access-Control-Allow-Origin值,解除跨域限制。
  • . . .