JSONP解决同源策略限制引起跨域问题原理
作者:Qing
这篇文章主要为大家介绍了JSONP解决同源策略限制引起跨域问题原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
同源策略的限制引起跨域问题
为了解决跨域问题,大家利用script标签请求src指向的资源不受同源策略限制的特性来进行资源的请求,这种方式就是JSONP。
接口实现
我们可以利用script标签请求资源不受同源策略限制的特性,可以自己简单的封装一个jsonp请求函数。
首先在js代码中手动创建script标签,把需要请求的资源放到src属性上,然后把script标签加入到body标签里面,在解析html的过程中就会执行,当执行完script并且请求到资源后,后端结果会以函数调用的的形式返回字符串类型的响应结果,这个形式的具体结构为函数名称(函数实参),和平时我们在调用函数时没有区别,然后页面就会执行后端返回的函数。
这里有个问题,页面会调用后端返回的函数,那么这个函数在哪里定义?
当然是要在本地的js代码里面定义这个函数,然后等待后端传递的参数,这个参数其实就是我们想要的返回结果。
// 简单写个序列化函数,不要就结是否考虑全面
function stringify(params) {
let res = "";
if (!params || typeof params !== "object") {
throw new Error("请传递参数对象");
}
Object.keys(params).forEach((key) => {
res += `&${key}=${params[key]}`;
});
return res.slice(1);
}
function jsonp({ url, params }) {
return new Promise((resolve) => {
const callback = `jsonp_${Math.ceil(Math.random() * 10000)}`;
const script = document.createElement("script");
script.src = `${url}?${stringify({ callback, ...params })}`;
document.body.appendChild(script);
// 一般情况下,函数的定义放置在window对象上,否则在调用函数的时候会找不到定义的实现
window[callback] = function (data) {
if (window[callback]) {
delete window[callback];
}
document.body.removeChild(script);
resolve(data);
};
});
}发送JSONP请求
利用封装的jsonp发起请求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>jsonp请求</title>
</head>
<body>
<button>点我就会biubiubiu地发送请求</button>
</body>
<script>
const button = document.querySelector("button");
button.onclick = function () {
jsonp({ url: "http://localhost:8888" }).then(console.log);
};
</script>
</html>服务端处理JSONP请求
jsonp请求需要服务端配合,约定查询参数callback是在本地定义好的函数,根据传递过来的callback返回其函数调用,并把数据通过实参的方式返回给客户端。
const http = require("http");
const url = require("url");
const qs = require("querystring");
const server = http.createServer((req, res) => {
const { query } = url.parse(req.url);
const params = qs.parse(query);
if (params.callback) {
const data = `${params.callback}(${JSON.stringify({ a: 1, b: 2 })})`;
res.end(data);
}
});
server.listen(8888, () => {
console.log("server is listen 8888");
});以上就是JSONP解决同源策略限制引起跨域问题原理的详细内容,更多关于JSONP同源策略跨域限制的资料请关注脚本之家其它相关文章!
