跨域哪些事——3. 使用JSONP实现跨域

社区前端
1.简介

如果还不了解跨域和同源策略的同学,可以去看一下第一篇,链接如下:链接如下:跨域哪些事——1.如果没有跨域,世界会是怎样? - 文章 - 开发者社区 - 火山引擎 (volcengine.com)

下面我们看一下什么是JSONP,jsonp的含义是:json with padding,而在json数据外包裹它的那个函数,是资料格式JSON的一种“使用模式”,可以让网页从别的网域获取资料。2005年夏天,乔治·詹姆提(George Jempty)建议在JSON前面选择性的加上变量赋值。鲍勃·伊波利托(Bob Ippolito)于2005年12月提出了JSONP最原始的提案,其中填充部分已经是回调函数,而现在已有很多Web 2.0应用程序使用这份提案,像是Dojo Toolkit应用程序、Google Web Toolkit应用程序与Web服务。

jsonp的官网:json-p.org/

2.原理

一般来说位于不同源的无法沟通,但是 script元素是一个例外,比如最常见的我们引入外部的jquery,不只是script,还包括img标签的src,或者说link标签的href他们没有被同源策略所限制。当链接的资源到达浏览器时,浏览器会根据他们的类型来采取不同的处理方式,比如,如果是css文件,则会进行对页面 repaint,如果是img 则会将图片渲染出来,如果是script 脚本,则会进行执行,比如我们在页面引入了jquery库,为什么就可以使用 了呢?就是因为jquery库被浏览器执行之后,会给全局对象window增加一个属性:了呢?就是因为 jquery 库被浏览器执行之后,会给全局对象window增加一个属性:了呢?就是因为jquery库被浏览器执行之后,会给全局对象window增加一个属性: ,所以我们才能使用 $ 来进行各种处理。另外为什么要一般要加css放在头部,而js脚本放在body尾部呢,就是为了减少repaint的次数,另外因为js引擎是单线程执行,如果将js脚本放在头部,那么在js引擎在执行js代码时,会造成页面暂停。而jsonp就是利用了script标签可以链接到不同源的js脚本,来到达跨域目的,网页可以得到从其他来源动态产生的JSON资料,而这种使用模式就是所谓的 JSONP。用JSONP抓到的资料并不是JSON,而是任意的JavaScript。

我们看一个例子:

前端

js
 代码解读
复制代码
<html> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.js"></script> <script> 
    function test(data){ 
        console.log(data); } 
</script>
<script src="http://localhost:3000/?fun=test"></script> 
</html>

后端:(nodejs为例)

js
 代码解读
复制代码
const http = require('http');
const querystring =require('querystring'); 
http.createServer((req,res)=>{ 
    //获取到url后的传的参数,处理成对象 
    var urlc = querystring.parse(req.url.split("?")[1]); 
    console.log(urlc);
    res.writeHead(200,{ "content-type":"text/html;charset=utf-8" }) 
    var data1 = { name:'lili' } 
    // res.write(data1);
    //将对象转换成json串,然后执行函数给传出去,抛出去执行外部的连接的代码。
    data1 = JSON.stringify(data1); 
    let callback = `${urlc.fun}(${data1})`; 
    res.end(callback) }).listen(3000,()=>{ console.log("服务跑在了3000端口上,地址为:http://localhost:3000") 
    })

后端相当于返回一段js代码,在前端有回调函数进行接收,接收后进行执行js函数,这个里面可以是纯数据,也可以是一些操作。

为了要启动一个JSONP调用(或者说,使用这个模式),你需要一个script 元素。因此,浏览器必须为每一个JSONP要求加(或是重用)一个新的、有所需 src值的script元素到HTML DOM里—或者说是“注入”这个元素。浏览器执行该元素,抓取src里的URL,并执行回传的 JavaScript。也因为这样,JSONP被称作是一种“让用户利用script元素注入的方式绕开同源策略”的方法。

picture.image

3.总结

从上图中我们可以看到,这个跨域完全是解决前端和服务器之间的跨域问题,也可以通过服务器中转解决一些前端页面和前端页面的跨域问题,并不能直接执行前端跨域问题,比如一个页面读取操作另一个页面数据的问题。而且由于是使用的script的标签,所以只支持get请求。

使用远程网站的script标签会让远程网站得以注入任何的内容至网站里。如果远程的网站有JavaScript注入漏洞,原来的网站也会受到影响。

粗略的JSONP部署很容易受到跨站请求伪造(CSRF/XSRF)的攻击。因为HTML的script标签在浏览器里不遵守同源策略,恶意网页可以要求并获取属于其他网站的JSON资料。当用户正登录那个其他网站时,上述状况使得该恶意网站得以在恶意网站的环境下操作该JSON资料,可能泄漏用户的密码或是其他敏感资料。

JSONP这种方式需要客户端和服务端定制进行开发,服务端返回的数据不能是标准的Json数据,而是callback包裹的数据。现在除了要适配一些较老的项目,现在应该使用的比较少。

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论