1.jsonp
使用 jsonp 来实现跨域请求,它的主要原理是通过动态构建 script 标签来实现跨域请求,因为浏览器对 script 标签的引入没有跨域的访问限制 。通过在请求的 url 后指定一个回调函数,然后服务器在返回数据的时候,构建一个 json 数据的包装,这个包装就是回调函数,然后返回给前端,前端接收到数据后,因为请求的是脚本文件,所以会直接执行,这样我们先前定义好的回调函数就可以被调用,从而实现了跨域请求的处理。这种方式只能用于 get 请求。
接下来我们通过一个实例来尝试:
前端逻辑
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
debugger
function jsonpCallback(data) {
console.log(data)
alert('获得 X 数据:' + data.x);
}
</script>
<script src="http://127.0.0.1:8000/api/blog/jsonp?callback=jsonpCallback"></script>
</body>
</html>
后端逻辑
router.get('/api/blog/jsonp', (req, res, next) => {
const callback = req.query.callback;
const data = {
x: 10
};
console.log(callback);
res.writeHead(200);
res.end(`${callback}(${JSON.stringify(data)})`)
});
优点:
- 它不像XMLHttpRequest 对象实现 Ajax 请求那样受到同源策略的限制
- 兼容性很好,在古老的浏览器也能很好的运行
- 不需要 XMLHttpRequest 或 ActiveX 的支持;并且在请求完毕后可以通过调用 callback 的方式回传结果。
缺点:
- 它支持 GET 请求而不支持 POST 等其它类行的 HTTP 请求。
- 它只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面或 iframe 之间进行数据通信的问题
- 无法捕获 Jsonp 请求时的连接异常,只能通过超时进行处理