跨域
是由浏览器发出的一个阻止,专门阻止AJAX;
如果被请求的路径和发起请求的路径非同源,浏览器则报出跨域错误;
解决跨域问题的方案:
-
CORS,在后端设置一个允许当前源的请求头即可。
浏览器 => 非常流行的跨域方案;跨域方案完全由后端解决;
-
jsonp跨域,所有的html标签的src请求都不受同源策略影响;
函数的参数传递;
function foo(data){
console.log(data);
}
//src 一定要加协议http
<script src = "http://localhost/data.php">
//JS的小秘密:无论加载的是什么内容(只要返回的是常规编码的字符),那么这个时候标签就会把它当成JS去解析,正是利用这一特性实现跨域
</script>
<?php
$data = "hello world";
echo "foo(\"$data\")";
?>
JSONP方法
-
什么是JSONP跨域
原理:src不受同源策略限制;
全局函数可以被外部函数调用;
函数可以传递参数;
此时的请求发送方式不再是xhr了,使用script标签发起请求;
服务器因为没有同源策略限制所以面对所有请求都会正确返回结果;
xxx.php = > 服务器看到请求是php后缀,会调用php解析器解析php代码,返回php解析结果;
php返回的结果一定是一个调用函数的字符串,其中需要返回的数据,作为实参放在函数调用之中;
这就是传说之中的野路子jsonp跨域;
需求分析;
1.动态创建script标签;
2.需要全局函数;
function jsonp( url , options ){
return new Promise(function( resolve , reject){
var global_name = "gp" + Math.random().toFixed(10).slice(2);
window[global_name] = function(data){
resolve(data);
}
url += (/\?/.test(url) ? "&" :"?") + (options.callback ? options.callback : "callback") + "=" + global_name;
for(var attr in options.data){
url += "&" + attr + "=" + options.data[attr];
}
var script = document.createElement("script");
script.src = url;
document.body.appendChild(script);
script.onload = function(){
this.remove();
}
})
}
var data = {
pre: 1,
p: 3,
json: 1,
prod: "pc",
from: "pc_web",
req: 2,
csor: 4,
_: Date.now()
};
var url = "https://www.baidu.com/sugrec";
var list = document.getElementById("list");
var input = document.getElementById("input");
var lock = null;
var delay = null;
input.oninput = function(){
// 去抖 => 无论你执行了多少次,我总在最后一次执行延时500ms触发;
clearTimeout(delay);
delay = setTimeout(function(){
lock = null;
search()
},500)
}
function search(){
var html = "";
data.wd = input.value;
jsonp(url,{callback:"cb" , data : data })
.then(function(data){
// console.log(data);
if(!data.g) return list.innerHTML = "";
data.g.forEach(function(item){
html += `<li>${item.q}</li>`;
})
list.innerHTML = html;
})
}