实现跨资源共享

通过XMLHttpRequest(XMR) 实现的Ajax 通信的一个主要限制就是跨域问题。默认情况下,XHR 对象只能访问与包含它的页面位于同一个域中的资源。

1,CORS 跨资源共享

CORS(Cross-Origin Resource Sharing 跨资源共享)解决了AJAX 跨域的问题。

跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。

CORS 通过使用自定义的 HTTP 头部让浏览器与服务器沟通,从而决定请求或相应是成功还是失败。

实现此功能非常简单,只需由服务器发送一个响应标头即可。假设 http://www.b.com 页面打算从 http://www.s.com 请求提取数据。如果直接用 AJAX 请求会返回“源不匹配”的错误,即跨域不允许。

利用 CORS, http://www.s.com 域要在被请求的php脚本头部添加
header(“Access-Control-Allow-Origin:http://www.b.com“); 就可以允许来自 http://www.b.com 的请求。

“*”号表示允许任何域向我们的服务端提交请求:
header(“Access-Control-Allow-Origin:*“);

不依赖XHR 对象,而是利用 DOM 中能够执行跨域请求的功能,也可以实现跨域通信。比如下面的 图像 Ping 和JSONP。

2,图像 Ping

一个网页可以再任何网页中加载图片,不用担心跨域问题,图片不受“同源策略”限制。这也是在线广告跟踪浏览量的主要方式。

缺点:只能发送GET 请求;无法访问服务器的响应文本。因此只能用于浏览器与服务器的单向通信。

3,JSONP

JSONP 看起来与JSON 差不多,只不过是被包含在函数调用中的JSONcallback({"name":"Nike"});.
从上面也可以看出,JSONP由回调函数和数据两部分组成。回调函数是当响应到来时应该在页面中调用的函数。回调函数是响应到来时应该在页面中调用的函数,而数据是传入回调函数中的JSON数据(服务器填充的)。

看到这里对JSONP的解释,清楚了很多:

1, web页面也可以执行跨域的 js 文件。
远程服务器remoteserver.com根目录下有个remote.js文件代码如下:

alert('我是远程文件');

本地服务器localserver.com下有个jsonp.html页面代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>

</body>
</html>

毫无疑问,页面将会弹出一个提示窗体,显示跨域调用成功。

2,现在我们在jsonp.html页面定义一个函数,然后在远程remote.js中传入数据进行调用。
jsonp.html 页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    var localHandler = function(data){
        alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
    };
    </script>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>

</body>
</html>

remote.js文件代码如下:

localHandler({"result":"我是远程js带来的数据"});

localHandler 是请求页面中的函数,上面的代码相当于把一个JSON数据{"result":"我是远程js带来的数据"} 通过函数localHandler (jsonp页面)的调用传入。
最后页面弹出窗口,正确显示。

但是又一个问题出现了,怎么让远程js知道它应该调用的本地函数叫什么名字呢?毕竟是jsonp的服务者都要面对很多服务对象,而这些服务对象各自的本地函数都不相同。

3,只要服务端提供的 js 脚本是动态生成的就可以了

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>

</body>
</html>

到调用的url中传递了一个code参数,告诉服务器我要查的是CA1998次航班的信息,而callback参数则告诉服务器,本地回调函数叫做flightHandler,所以请把查询结果传入这个函数中进行调用。

服务器很聪明,这个叫做flightResult.aspx的页面生成了一段这样的代码提供给jsonp.html

flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});

3,JSONP 与 Ajax 异同

  1. 目的相同,都是请求一个url,将服务器返回的数据进行处理。因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;
    2. 但是Ajax 是通过XMLHttpRequest 获取非本页面的内容,jsonp 是通过动态添加<script> 标签来调用服务器提供的 js 脚本.

参考:
http://www.web-fish.com/program/php/794.html
http://www.bestphper.cn/article-283.html
http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html#top

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值