-
Notifications
You must be signed in to change notification settings - Fork 120
Open
Description
一个 JSONP 的步骤实质
客户端发送 script 请求,参数中带着处理返回数据的回调函数的名字 (通常是 callback),如请求 script 的 url 是:
http://127.0.0.1:8000/?callback=getMsg
服务端收到请求,以回调函数名和返回数据组成立即执行函数的字符串,比如:其中 callback 的值是客户端发来的回调函数的名字,假设回调函数的名字是 getMsg,返回脚本的内容就是:
getMsg("{name: 'Yang Min', age: '8'}");
客户端收到 JavaScript 脚本内容后,立即执行脚本,这样就实现了获取跨域服务器数据的目的。
很明显,由于 JSONP 技术本质上利用了 script 脚本请求,所以只能实现 GET 跨域请求,这也是 JSONP 跨域的最大限制。
由于 server 产生的响应为 json 数据的包装(故称之为 jsonp,即 json padding),形如:getMsg("{name: 'Yang Min', age: '8'}")
JSONP 封装
客户端参考代码:
const jsonp = ({ url, params, callbackName }) => {
const generateURL = () => {
let dataStr = "";
for (let key in params) {
dataStr += `${key}=${params[key]}&`;
}
dataStr += `callback=${callbackName}`;
return `${url}?${dataStr}`;
};
return new Promise((resolve, reject) => {
// 初始化回调函数名称
callbackName =
callbackName ||
"cb" +
Math.random()
.toString()
.replace(".", "");
let scriptEle = document.createElement("script");
scriptEle.src = generateURL();
document.body.appendChild(scriptEle);
// 绑定到 window 上,为了后面调用
window[callbackName] = data => {
resolve(data);
// script 执行完了,成为无用元素,需要清除
document.body.removeChild(scriptEle);
};
});
};
jsonp({
url: "http://127.0.0.1:8000/",
params: {
name: "Yang Min",
age: "8"
},
callbackName: "getData"
})
.then(data => JSON.parse(data))
.then(data => {
console.log(data); // {name: "Yang Min", age: "8"}
});
Metadata
Metadata
Assignees
Labels
No labels