ajax问题
浏览器同源策略
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源
源 :协议、域名和端口号
跨域
不受同源策略影响的资源的引入
<script src="..."></script>,<img>,<link>,<iframe>
JSONP (JSON with Padding)
解决跨域问题;可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
jsonp原理
通过 script标签 来实现跨域
服务端实现
请求百度接口
https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=hello&cb=succFn
ajax封装加入jsonp
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>点击请求jsonp</button>
</body>
<script>
let btn = document.querySelector("button");
btn.onclick = function(){
ajax({
url:"http://localhost:4000/getAjax",
data:{
name:"张三",
age:20
},
dataType:"jsonp",
jsonp:"callback",
success:function(res){
console.log(res)
}
})
}
function ajax(options) {
let opts = Object.assign({
method: 'get',
url: '',
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
jsonp:"cb",
data: '',
success: function () { }
}, options)
//处理jsonp请求;
if(opts.dataType==="jsonp"){
jsonpFn(opts.url,opts.data,opts.jsonp,opts.success);
return false;
}
function jsonpFn(url,data,cbName,cbFn){
// cbName cb/callback
let fnName = "KKB_"+Math.random().toString().substr(2);
window[fnName] = cbFn;
let path = url+"?"+o2u(data)+"&"+cbName+"="+fnName;
// console.log(path);
let o = document.createElement("script");
o.src = path;
document.querySelector("head").appendChild(o);
}
let xhr = new XMLHttpRequest();
if (options.method == "get") {
let data = o2u(opts.data)
options.url = options.url + "?" + data;
}
xhr.open(options.method, options.url, true);
for (let key in opts.headers) {
xhr.setRequestHeader(key, opts.headers[key]);
}
let sendData;
switch (opts.headers['content-type']) {
case 'application/x-www-form-urlencoded':
sendData = o2u(opts.data);
break;
case 'application/json':
sendData = JSON.stringify(opts.data);
break;
}
xhr.onload = function () {
let resData;
if (xhr.getResponseHeader("content-type").includes("xml")) {
resData = xhr.responseXML;
} else {
resData = JSON.parse(xhr.responseText);
}
options.success(resData);
}
if (options.method == "get") {
xhr.send();
} else {
xhr.send(sendData);
}
}
function o2u(obj) {
let keys = Object.keys(obj);
let values = Object.values(obj);
return keys.map((v, k) => {
return `${v}=${values[k]}`;
}).join("&");
}
</script>
</html>