最新的Yusi主题上线啦!

深入理解JSONP

web lzxianren 648℃ 0评论

JSONP是什么?

JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

同源策略

同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。此限定由浏览器执行,主流厂商的浏览器都支持,是W3C的标准。

什么是一个源?

如果协议,端口(如果指定了一个)和域名对于两个页面是相同的,则两个页面具有相同的

下表给出了相对http://store.company.com/dir/page.html同源检测的示例:

URL 结果 原因
http://store.company.com/dir2/other.html 成功  
http://store.company.com/dir/inner/another.html 成功  
https://store.company.com/secure.html 失败 不同协议 ( https和http )
http://store.company.com:81/dir/etc.html 失败 不同端口 ( 81和80)
http://news.company.com/dir/other.html 失败 不同域名 ( news和store )

三个相同:

  • 协议相同
  • 域名相同
  • 端口相同

同源政策的目的

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么?

很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。

由此可见,”同源政策”是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。

限制范围

  1.  Cookie、LocalStorage 和 IndexDB 无法读取。
  2.  DOM 无法获得。
  3.  AJAX 请求不能发送。

本文不过多介绍浏览器的同源策略,只需要了解这个概念。如果大家想了解更多,可以阅读阮一峰的博客

JSONP是解决Ajax同源问题的一种方案,其它的还有Websocket,CORS。

JSONP原理

通俗来讲,JSONP就是利用script标签(GET请求,非跨域)来实现Ajax跨域通信。

下面通过几段代码来模拟这个过程。

模拟一

很简单的一段代码,只是把我们平常写在一块的函数定义和函数调用分开了。但已经有了JSONP的雏形。

模拟二

jsonp.js里面的内容就是上面模拟一的第二个script标签的内容,其实就是把js又分文件了。

模拟三

后面这段就是一个java的普通的servlet代码,把原来在js文件中的代码用一个servlet写回来。这已经快是工程实践中的jsonp了。这段的问题是callback这个function名字写死了。

模拟四

算了,相信大家已经搞明白了。模拟四就不再写新代码了。

来一段jquery的代码吧。

服务端就是在原来的json基础上搞一个拼接就好了。

总结一下:

AJAX 无法跨域是受到“同源政策”的限制,但是带有src属性的标签(例如<script><img><iframe>)是不受该政策限制的,因此我们可以通过向页面中动态添加<script>标签来完成对跨域资源的访问,这也是 JSONP 方案最核心的原理。

通常我们使用<script>都是引用的静态资源(主要是 js 文件),其实它也可以用来引用动态资源(php、jsp、aspx等),后台服务被访问后返回一个“JavaScript函数调用”形式的字符串,由于是字符串,因此在后台的时候不会起到任何作用,但到了前台,放入<script>标签之内,就成了一个合法的 JavaScript 函数调用,实参是我们真正需要的数据,被调用的回调函数也已经实现了,因此就会顺利的被调用。

再次强调:JSONP 不是 AJAX,了解了它的原理之后你应该已经明白这是为什么了(事实上 JSONP 的出现让 “AJAX跨域请求”变成了伪命题,跨域的过程根本就没 AJAX 什么事)。要怪就怪 jQuery,给不明真相的吃瓜群众带来了误解。当然 jQuery 这么做也不无道理,毕竟跨域的问题是在 AJAX 中遇到的,受惯性思维影响我们自然首先会从 AJAX 的角度去寻求解决方案,因此 jQuery 才把 JSONP 封装到了$.ajax()的配置项中,至于具体的实现自然还是上面提到的方法。

回过头来我们再看一遍 JSONP 的全称:JSON with Padding,这里的 Padding 指的就是包裹在 JSON 外层的回调函数,这么一来,是不是印象就非常深刻了呢。

spring boot/mvc怎么写?

简单的要死啊!

就配一个Advice就好了,反正jq默认的回调就是这个callback。

转载请注明:程序员的自我修养 » 深入理解JSONP

喜欢 (1)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址