前言
JSONP(JSON with Padding)是一种用于跨域数据传输的技能。在欣赏器的同源计谋限定下,一样平常环境下,JavaScript 不能直接从差异域的服务器获取数据。JSONP 通过利用 <script> 标签的跨域特性来绕过这个限定。
它本质上是一种非官方的跨域数据交互办理方案,重要用于从差异域名的服务器获取数据,在前后端分离的开辟模式以及与第三方 API 交互等场景中发挥着告急作用。
一、利用场景
- 跨域数据获取:在前后端分离的项目中,前端应用(如运行在 http://localhost:3000)须要从后端服务器(如 http://api.example.com)获取数据时,当后端服务器没有设置 CORS(跨域资源共享),JSONP 是一种简朴的跨域办理方案。
- 与第三方 API 交互:当利用一些第三方的 API 服务,且这些服务支持 JSONP 时,也可以利用 JSONP 来获取数据。比方,一些气候 API、舆图 API 等,在不支持 CORS 大概为了简朴快速地获取数据时,可以思量利用 JSONP。
二、JSONP工作原理
利用<script>标签:欣赏器在加载 JavaScript 脚本时,不受同源计谋的限定。JSONP 利用了这一点,在客户端通过动态创建 <script> 标签来哀求服务器数据。比方,假设服务器端提供了一个接口 http://example.com/api?callback=myCallback,客户端会动态创建一个如下的 <script> 标签:- <script src="http://example.com/api?callback=myCallback"></script>
复制代码 服务器相应:服务器收到哀求后,会将数据包装在指定的回调函数(这里是 myCallback)中返回。比方,服务器返回的数据大概是如许的格式:myCallback({ "data": "value" })。当欣赏器吸收到这个相应并将其作为脚本实行时,现实上是在调用客户端预先界说好的 myCallback 函数,并将数据作为参数传入。
客户端处置惩罚:在客户端,须要预先界说好这个 myCallback 函数来吸收和处置惩罚服务器返回的数据。比方:- function myCallback(data) {
- console.log(data);
- }
复制代码 客户端打印出来的data就是服务端传过来的数据
三、JSONP长处
- 简朴易用:JSONP 的实现相对简朴,对于只须要获取数据的跨域场景,通过简朴地创建 <script> 标签和界说回调函数就可以实现。与一些复杂的跨域办理方案(如 CORS)相比,它的代码复杂度较低。
- 兼容性好:险些全部的欣赏器都支持通过 <script> 标签加载外部脚本,以是 JSONP 在各种欣赏器环境下都能很好地工作,不须要思量欣赏器兼容性标题。
四、JSONP缺点
- 安全风险:由于 JSONP 是通过 <script> 标签加载数据,这就意味着服务器返回的数据会被看成 JavaScript 代码来实行。如果服务器被攻击者控制,返回恶意代码,那么客户端就会实行这些恶意代码,导致安全标题,如 XSS(跨站脚本攻击)。
- 只能用于 GET 哀求:JSONP 是基于 <script> 标签的机制,而 <script> 标签只能发起 GET 哀求。以是,如果须要举行 POST 等其他范例的哀求,JSONP 就无法满足需求。
五、HTTP模块实现JSONP跨域传值
服务端:
当服务器吸收到哀求时,须要查抄哀求的 URL 参数,看是否包罗一个用于 JSONP 的回调函数名称(通常通过类似callback的参数指定)。比方,在一个http模块创建的服务器中,可以在哀求处置惩罚函数中查抄:- //使用http模块创建服务器,我们建议使用commonjs模块规范,因为很多第三方的组件都使用了这种规范。当然es6写法也支持。
- //http模块式Node.js内置的模块,用于创建和管理HTTP服务器。传统的HTTP服务器一般使用C语言编写,但Node.js使用JavaScript实现,因此性能更好。
- const http = require('http')
- //url模块用于解析url参数
- const url=require('url');
- //创建服务器,监听3000端口
- http.createServer((req, res) => {
- //判断请求url是否为favicon.ico,如果是则返回空(这个请求是一个浏览器的默认请求,可以忽略)
- if (req.url === '/favicon.ico') {
- return
- }
- //设置响应头,状态码为200,内容类型为text/html;charset=utf-8,这种才能正常显示中文
- res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'})
- //解析url参数,这里的第二个参数为true,表示解析query字符串,返回object格式
- const parsedUrl = url.parse(req.url,true);
- console.log(parsedUrl);
- let {pathname,query}=parsedUrl;
- //callback参数中可以指定回调函数名,这里我们取名为callback(不一定要叫callback,可以随意取,但是要和客户端请求时一致)
- let {callback}=query;
- //如果有callback参数,则说明是jsonp请求,返回jsonp格式的数据
- if(callback){
- res.write(`${callback}(${JSON.stringify({name:'zhangsan',age:20})})`)
- }
- //这里必须要end,否则会出现卡死的情况
- res.end()
- }).listen(3000, () => {
- console.log('Server is running on port 3000')
- })
复制代码 客户端:
我们创建一个index.html页面,在内里创建一个script标签,实现哀求jsonp服务端接口的客户端。
index.html文件如下:- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h1>jsonp接口调用测试</h1>
- <script>
- // 创建一个script标签,设置src属性为jsonp接口地址,并设置回调函数名为jsonpCallback
- let script = document.createElement('script')
- script.src = 'http://localhost:3000/jsonp?callback=jsonpCallback';
- //添加到body中,加载这个页面的时候就会自动执行这个script标签,发起jsonp请求
- document.body.appendChild(script);
- // 定义回调函数,接收jsonp接口返回的数据(这里的回调函数名要和jsonp接口地址中的callback参数保持一致)
- function jsonpCallback(data) {
- console.log('jsonp服务端接口返回的数据:',data)
- }
- </script>
- </body>
- </html>
复制代码 实行启动index.html文件,就会向服务器发送哀求,我们查察服务器是否通过回调(这里是jsonpCallback函数)返回数据,并打印。
从上图可以看到返回的数据乐成打印,可以看到通过回调传过来的数据。
以上就是http模块实现JSONP跨域传值的实现过程。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |