前后端交互 — jsonp
知识要点
- 跨域解决
- jsonp原理及封装
- jsonp服务器搭建
- jsonp实际运用
ajax问题
-
浏览器同源策略
- 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源
- 源 :协议、域名和端口号
-
跨域
-
不受同源策略影响的资源的引入
- ,,,
jsonp
JSONP*(JSON with Padding)解决跨域问题;可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
-
jsonp原理
-
通过script来实现跨域;
-
服务端实现
-
实现动态数据的获取及渲染
https://list.mogu.com/search?callback=jQuery2110599693622515429_1558943916971&_version=8193&ratio=3%3A4&cKey=15&page=1&sort=pop&ad=0&fcid=52014&action=food
请求实现
ajax({
url: "https://list.mogu.com/search",
data: {
_version: 8193,
ratio: "3%3A4",
cKey: 15,
page: page,
sort: "pop",
ad: 0,
fcid: 52014,
action: "food"
},
dataType: "jsonp",
jsonp: "callback",
success: function (res) {
if (res.status.code == 1001) {
page++;
let data = res.result.wall.docs;
// console.log(data);
data.forEach(item => {
createEelement(item);
})
}
}
})
##jsonp封装
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("&");
}
- jsonp问题
1.只能是get请求
2.安全性问题
总结
- jsonp原理
- jsonp封装
- 会搭建node服务器创建jsonp接口
- jsonp实际运用