平时工做当中,也已经好久没有用JSONP 来跨域请求了,现从新整理一下,写出本身对 JSONP 的理解。若是写的有不对的,请各位看官评论指出,感谢。
行文时,系统环境为 macOS Mojave v10.14.5,开发工具为 vscode 1.45.1,浏览器为 Goolge Chrome 版本 81.0.4044.138 。 javascript
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。html
这是引用了百度百科对 JSONP 的定义。笔者本身的理解是, JSONP 是一种利用浏览器 script 标签的能力实现访问跨域数据的小技巧。就是利用 script 标签能访问跨域资源的能力,利用 JSON 去填充返回内容,以达到跨域的目的。 前端
上文说到了,JSONP 解决了跨域问题。那啥是跨域呢,简单说就是发起请求的网站与被请求的网站,它俩的协议、主机、端口不是彻底同样的。表现就是,跨域时,请求是不会成功的。
JSONP 究竟是怎么实现的呢,笔者的理解是,基于下面三点实现的:java
接下来就写点代码测试一下,并用大白话把过程描述一下。
用koa模拟服务端,代码以下面试
const koa = require("koa");
const mount = require("koa-mount");
const app = new koa();
app.use(
mount("/jsonp", (ctx) => {
let callback = ctx.query.abc;
let javascriptFileText = ` console.log(1); ${callback}("这是服务端的内容"); `;
ctx.body = javascriptFileText;
})
);
app.listen(8123);
复制代码
前端代码以下json
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>client</title>
</head>
<body>
<script> function handler(res) { console.log(res) } window.addEventListener('load', () => { var url = 'http://127.0.0.1:8123/jsonp?abc=handler' var script = document.createElement('script'); script.src = url // 把script标签塞入到文档里,就会发起请求 document.getElementsByTagName('head')[0].appendChild(script); }) </script>
</body>
</html>
复制代码
笔者认为的过程以下:跨域
console.log(1)
和一个函数调用,在这个调用里传入 "这是服务端的内容" 。对于服务端来讲,这一段始终是字符串文本。console.log(1);handler("这是服务端的内容")
这样的内容,而后浏览器 JS引擎 就把这段内容执行,能够对应 eval() 理解。执行的时候,是处于 全局上下文 的。因此是能拿到 handler 这个函数的。而后呢,在 handler 里就经过res拿到了服务端传回给前端的内容。是否是很妙?!!我第一次用的时候,真的是眼前一亮,原来能够这么玩。handler(this)
,而后前端页面里拿到的就是 handler 函数执行上下文里的 this 变量了,一样,这样写没有任何意义,只会被打而已。也能够写成 handler('name="服务端给的name"&age="服务端给的age"')
,这样,经过 & 和 = 去切割获取内容,这样也很麻烦呀,因此最终你们都选择传 JSON 格式的内容,这是最方便获取内容的方式。因此就叫 JSONP 。(这样看来,是否是也能够叫 callbackP 、 STRINGP 呢??) JSONP 这种技巧,如今(2020-06-01)已经不多有听到有还在使用的。由于现代浏览器基本都支持了 CORS 标准,这可比只支持 GET 的 JSONP 强太多了。之后,笔者估计本身是不会用到 JSONP 了,这篇文章只是笔者看到有些公司在面试时,仍是会问 JSONP 的内容。因此就记录一下。浏览器