JSONP
若是两个页面拥有相同的协议,端口(若是指定),和主机,那么这两个页面就属于同一个源。
同源策略分为:javascript
DOM
同源策略:禁止对不一样源页面DOM
进行操做html
XMLHttpRequest
同源策略:禁止向不一样源的地址发起HTTP
请求
因而可知,Ajax
禁止跨域。java
JSONP
的原理JSONP
是JSON with Padding
的简称,通常用来解决Ajax
跨域的问题。它是这样产生的:jquery
页面上调用js
文件时不受跨域的影响,并且,凡是拥有src
属性的标签都拥有跨域的能力,好比<script>
、<img>
、<iframe>
。ajax
能够在远程服务器上设法把数据装进js
格式的文件里,供客户端调用处理,实现跨域。json
目前最经常使用的数据交换方式是JSON
,客户端经过调用远程服务器上动态生成的js
格式文件(通常以JSON
后缀)。跨域
客户端成功调用JSON
文件后,对其进行处理。浏览器
为了便于客户端使用数据,逐渐造成了一种非正式传输协议,人们把它称做JSONP
,该协议的一个要点就是容许用户传递一个callback
参数给服务端,而后服务端返回数据时会将这个callback
参数做为函数名来包裹住JSON
数据,这样客户端就能够随意定制本身的函数来自动处理返回数据了。安全
JSONP
的客户端具体实现2.1 上文已指出,页面可执行跨域的js
代码(符合安全策略的),那么:服务器
<script type="text/javascript"> var localHandler = function (data) { alert('跨域的remote.js文件能够调用本函数,带来的数据是:' + data.result); }; </script> <script type="text/javascript" src = "http://remoteserver.com/remote.js"></script>
remote.js
的代码:
localHandler({ "result": "我是远程js带来的数据" });
运行后,成功弹出提示窗口,跨域成功。但问题是,如何让远程js
知道它应该调用的本地函数叫什么名字?
2.2 只要服务端提供的js
脚本是动态生成的就好了,调用者能够传一个参数过去告诉服务端本地函数的名字,因而服务端就能够按照客户的需求来生成js
脚本并相应了。
var flightHandler = function (data) { alert('你查询的航班结果是:票价 ' + data.price + '元,余票' + data.tickets + '张。'); }; var url = 'http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler'; var script = document.createElement('script'); script.setAttribute('src', url); document.getElementsByTagName('head')[0].appendChild(script);
并无直接把远程js
写死,而是编码事项动态查询。这是JSONP
的核心部分。在调用的url
中传递了一个code
参数,告诉服务器要查的是CA1998
次航班的信息,而callback
参数告诉服务器,本地调用的函数叫作flightHandler
。
服务器的flightResult.aspx
生成了如下代码提供给页面:
flightHandler({ "code": "CA1998", "price": 1780, "tickets": 5 });
运行一下页面,成功提示窗口,JSONP
的执行全过程顺利完成。
2.3 jQuery
代码
$(function() { $('button').on('click', function(event) { event.preventDefault(); $.ajax({ type: 'GET', async: false, url: 'http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998', dataType: 'jsonp', jsonp: 'callback', jsonpCallback: 'flightHandler', // 默认为jQuery自动生成的随机函数名 success: function (json) { alert('你查询的航班结果是:票价 ' + json.price + '元,余票' + json.tickets + '张。'); }, error: function () { alert('fail'); } }); }); });
jQuery
自动生成回调函数并把数据取出来供success
属性方法来调用。
JSONP
与Ajax
的关系Ajax
与JSONP
这两种技术看起来很像,目的也同样,都是请求一个url
,而后把服务器返回的数据进行处理,所以jQuery
等框架都把JSONP
做为Ajax
的一种形式。
实际上Ajax
与JSONP
有着本质上的不一样。Ajax
的核心是经过XMLHttpRequest
获取数据,而JSONP
的核心则是动态添加<script>
标签来调用服务器提供的js
文件。
Ajax
与JSONP
的区别也不在因而否跨域,Ajax
经过服务端代理也能够跨域,JSONP
也可获取同源数据。