关于jsop跨域问题
Ajax是驱动新⼀代 Web 站点(流⾏术语为 Web 2.0 站点)的关键技术。Ajax 允许在不⼲扰 Web 应⽤程序的显⽰和⾏为的情况下在后台进⾏数据检索。使⽤XMLHttpRequest函数获取数据,它是⼀种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器。Ajax 也是许多mashup 的驱动⼒,它可将来⾃多个地⽅的内容集成为单⼀ Web 应⽤程序。
不过,由于受到浏览器的限制,该⽅法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。如果能控制数据驻留的远程服务器并且每个请求都前往同⼀域,就可以避免这些安全错误。但是,如果仅停留在⾃⼰的服务器上,Web 应⽤程序还有什么⽤处呢?如果需要从多个第三⽅服务器收集数据时,⼜该怎么办?
理解同源策略限制
同源策略阻⽌从⼀个域上加载的脚本获取或操作另⼀个域上的⽂档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页⾯的域相同。这意味着浏览器隔离来⾃不同源的内容,以防⽌它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。
克服该限制的⼀个相对简单的⽅法是让 Web 页⾯向它源⾃的 Web 服务器请求数据,并且让 Web 服务器
像代理⼀样将请求转发给真正的第三⽅服务器。尽管该技术获得了普遍使⽤,但它是不可伸缩的。另⼀种⽅式是使⽤框架要素在当前 Web 页⾯中创建新区域,并且使
⽤GET请求获取任何第三⽅资源。不过,获取资源后,框架中的内容会受到同源策略的限制。
克服该限制更理想⽅法是在 Web 页⾯中插⼊动态脚本元素,该页⾯源指向其他域中的服务 URL 并且在⾃⾝脚本中获取数据。脚本加载时它开始执⾏。该⽅法是可⾏的,因为同源策略不阻⽌动态脚本插⼊,并且将脚本看作是从提供 Web 页⾯的域上加载的。但如果该脚本尝试从另⼀个域上加载⽂档,就不会成功。幸运的是,通过添加 JavaScript Object Notation (JSON) 可以改进该技术。
1、什么是JSONP?
要了解JSONP,不得不提⼀下JSON,那么什么是?
JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the
language with no muss or fuss.
JSONP(JSON with Padding)是⼀个⾮官⽅的协议,它允许在服务器端集成Script tags返回⾄客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
2、JSONP有什么⽤?
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端⼝)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执⾏回调函数,从⽽解决了跨域的数据请求。
3、如何使⽤JSONP?
下边这⼀DEMO实际上是JSONP的简单表现形式,在客户端声明回调函数之后,客户端通过script标签向服务器跨域请求数据,然后服务端返回相应的数据并动态执⾏回调函数。
HTML代码(任⼀):
Html代码
1. <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
2. <script type="text/javascript">
3.    function jsonpCallback(result) {
4.        //alert(result);
5.        for(var i in result) {
6.            alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
7.        }
8.    }
9.    var ateElement("script");
10.    pe="text/javascript";
11.    JSONP.src="crossdomain/services.php?callback=jsonpCallback";
12.    ElementsByTagName("head")[0].appendChild(JSONP);
13. </script>
或者
Html代码
1. <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
2. <script type="text/javascript">
3.    function jsonpCallback(result) {
4.        alert(result.a);
5.        alert(result.b);
6.        alert(result.c);
7.        for(var i in result) {
8.            alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
9.        }
10.    }
11. </script>
12. <script type="text/javascript" src="crossdomain/services.php?callback=jsonpCallback"></script>  JavaScript的链接,必须在function的下⾯。
服务端PHP代码(services.php):
Php代码
1. <?php
2.
3. //服务端返回JSON数据
4. $arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
5. $result=json_encode($arr);
6. //echo $_GET['callback'].'("Hello,World!")';
7. //echo $_GET['callback']."($result)";
8. //动态执⾏回调函数
9. $callback=$_GET['callback'];
10. echo $callback."($result)";
如果将上述JS客户端代码⽤jQuery的⽅法来实现,也⾮常简单。
$.getJSON
$.ajax
$.get
客户端JS代码在jQuery中的实现⽅式1:
Js代码
1. <script type="text/javascript" src="jquery.js"></script>
2. <script type="text/javascript">
3.    $.getJSON("crossdomain/services.php?callback=?",
4.    function(result) {
5.        for(var i in result) {
6.            alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
7.        }
8.    });
9. </script>
客户端JS代码在jQuery中的实现⽅式2:
Js代码
1. <script type="text/javascript" src="jquery.js"></script>
2. <script type="text/javascript">
3.    $.ajax({
4.        url:"crossdomain/services.php",
5.        dataType:'jsonp',
6.        data:'',
7.        jsonp:'callback',
8.        success:function(result) {
9.            for(var i in result) {
10.                alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
11.            }
12.        },
13.        timeout:3000
14.    });
15. </script>
客户端JS代码在jQuery中的实现⽅式3:
Js代码
1. <script type="text/javascript" src="jquery.js"></script>
2. <script type="text/javascript">
3.    $.get('crossdomain/services.php?
callback=?', {name: encodeURIComponent('tester')}, function (json) { for(var i in json) alert(i+":"+json[i]); }, 'jsonp');
4. </script>
Js代码
1. jsonpCallback({msg:'this is json data'})
Jsonp原理:
⾸先在客户端注册⼀个callback, 然后把callback的名字传给服务器。
此时,服务器先⽣成 json 数据。
然后以 javascript 语法的⽅式,⽣成⼀个function , function 名字就是传递上来的参数 jsonp.
最后将 json 数据直接以⼊参的⽅式,放置到 function 中,这样就⽣成了⼀段 js 语法的⽂档,返回给客户端。
客户端浏览器,解析script标签,并执⾏返回的 javascript ⽂档,此时数据作为参数,传⼊到了客户端预先定义好的 callback 函数⾥.(动态执⾏回调函数)
使⽤JSON的优点在于:
⽐XML轻了很多,没有那么多冗余的东西。浏览器json格式化
JSON也是具有很好的可读性的,但是通常返回的都是压缩过后的。不像XML这样的浏览器可以直接显⽰,浏览器对于JSON的格式化
的显⽰就需要借助⼀些插件了。
在JavaScript中处理JSON很简单。
其他语⾔例如PHP对于JSON的⽀持也不错。
JSON也有⼀些劣势:
JSON在服务端语⾔的⽀持不像XML那么⼴泛,不过上提供很多语⾔的库。
如果你使⽤eval()来解析的话,会容易出现安全问题。
尽管如此,JSON的优点还是很明显的。他是Ajax数据交互的很理想的数据格式。
主要提⽰:
JSONP 是构建 mashup 的强⼤技术,但不幸的是,它并不是所有跨域通信需求的万灵药。它有⼀些缺陷,在提交开发资源之前必须认真考虑它们。
第⼀,也是最重要的⼀点,没有关于 JSONP 调⽤的错误处理。如果动态脚本插⼊有效,就执⾏调⽤;如果⽆效,就静默失败。失败是没有任何提⽰的。例如,不能从服务器捕捉到 404 错误,也不能取消或
重新开始请求。不过,等待⼀段时间还没有响应的话,就不⽤理它了。(未来的 jQuery 版本可能有终⽌ JSONP 请求的特性)。
JSONP 的另⼀个主要缺陷是被不信任的服务使⽤时会很危险。因为 JSONP 服务返回打包在函数调⽤中的 JSON 响应,⽽函数调⽤是由浏览器执⾏的,这使宿主 Web 应⽤程序更容易受到各类攻击。如果打算使⽤ JSONP 服务,了解它能造成的威胁⾮常重要。