理解JSONP

被问到如何绕开浏览器中javascript的同源策略时,大多数人会提到JSONP这个方案,或许也会提到其他方案(比如代理或者CORS),但是并不能清楚的解释究竟哪种方案更好。这篇文章会回答上述问题。

一、JSONP是什么?

如果你熟知javascrpt在浏览器中的运行机制,你可能知道通过script标记的src属性引入的脚本不受同源策略的限制。例如,当我们从Google的cdn节点或者其他源加载jquery库时,它跟我们的当前页面并不是同源的。

同理,利用script标记可以尝试加载除了库文件之外的其它类型的javascript。由于javascript有一个全局作用域,设想你用script标签加载的文件中执行了一个全局的函数,这个函数的参数是你应用中要用到的数据,这就是JSNOP的实现思路。

JSONP的实现思路很简单:

在文档中插入一个script标签,这个标签引用一个返回json数据的资源。服务器端返回的是加了装饰的JSON,即返回的是函数执行,而结果数据被作为函数执行的参数使用的,因此服务器端的api必须也要支持JSONP。通常,在请求JSONP接口时,函数名必须作为callback参数传递。举例,假设你访问一个返回JSON格式的天气信息的服务,接口如下:

http://www.weather.com/90210

这个接口返回的JSON格式的数据是这样的

{"zipCode": "90210","location": "Beverly Hills","high": "85 degrees","low": "55 degrees"}

服务端api支持JSONP的话,接口是这样的

http://www.weather.com/90210?callback=MyCallback

返回的数据格式是这样的

MyCallback({"zipCode": "90210","location": "Beverly Hills","high": "85 degrees","low": "55 degrees"});

只要MyCallback是全局作用域中的有效函数,json数据在程序的其他地方是可访问的。

在jquery这样的前端库中,JSONP的实现方式是自动生成一个回调函数,当回调函数执行时会立刻将插入的script标记删除。

 

二、为什么要用JSONP

  1. 主流浏览器都支持JSONP,此外很多API服务也支持JSONP的形式调用。
  2. 一个XMLHttpRequest请求和DOM的改动就可以以低成本实现跨浏览器
  3. 主流的前端库和框架都实现了JSONP

三、JSONP的缺点

  1. jsonp是通过script标记实现的,所以只能用GET方法。不符合Restful api的设计规范,同时也只能用url params的方式传参。
  2. jsonp依赖script标记,没有统一的捕获错误的机制。不是所有些浏览器都可以去侦听script的相应的事件,因此不得不使用hacks
  3. jsonp绕开了同源策源,为程序带来了安全隐患

四、JSONP的替代方案

  1. 配置代理 在服务器上对于非同源的外部API设置代理,例如在Ngnix上,设置proxy_pass字段
  2. HTTP访问控制(CORS)

如果不考虑IE7及以下浏览器,也不用关心opera,CORS是实现跨域最好的方案。理由如下

  1. 支持所有HTTP请求方式
  2. 支持错误捕获
  3. 安全系数高
  4. IE8+浏览器支持,并且在服务器端实现简单

缺点就是主流JSONP APIs还不支持

五、结论

CORS >= Proxy > JSONP

 

原文地址:

https://johnnywey.wordpress.com/2012/05/20/jsonp-how-does-it-work/

posted on 2017-12-14 17:37  chilebaby  阅读(158)  评论(0编辑  收藏  举报

导航