解决js跨域问题的基本方法之 -------JSONP

时间:2022-08-28 15:53:15

首先,我们需要了解什么是跨域,通俗的说,跨域可以简单的说成跨不同的域名,那么什么称得上是不同的域呢?----只要协议、域名、端口有任何一个不同,都被当作是不同的域。

URL                      说明                    是否允许通信
http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.js http://www.a.com/script/b.js 同一域名下,不同文件夹 允许 http://www.a.com:8000/a.js http://www.a.com/b.js 同一域名,不同端口 不允许 http://www.a.com/a.js https://www.a.com/b.js 同一域名,不同协议 不允许 http://www.a.com/a.js http://70.32.92.74/b.js 域名和域名对应ip 不允许 http://www.a.com/a.js http://script.a.com/b.js 主域相同子域不同  不允许 http://www.a.com/a.js http://a.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问) http://www.cnblogs.com/a.js http://www.a.com/b.js 不同域名   不允许

对于端口和协议的不同,只能通过后台来解决。
我们可以通过以下的方法来解决跨域的问题:
jsonp、document.domain+iframe、window.name、window.postMessage、服务器上设置代理页面

首先们要清楚什么是jsonp,它是JSON with padding(填充式json或参数式json)的简写,是应用json的一种新方法。jsonp看起来和json差不多,不过jsonp是将json包含在函数中调用。

就像这样:callback({"name": "nick"});

JSONP是由两部分组成的:回调函数和数据。回调函数是当我们的响应来到页面中时我们需要调用的函数;而数据就是需要传入回调函数中的json数据。

JSONP是通过动态创建script标签,用script标签中的src属性来指定跨域的url进行访问的,因为script标签和我们常用的img标签相同,都是不受域名限制的,都可以无限制的从其他域加载资源。

在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。

<script type="text/javascript">
    function dosomething(jsondata){
        //处理获得的json数据
    }
</script>
//动态创建好script标签
<script>
var oScript = document.createElement('script');

  oScript.src = "http://url?&callback=dosomething"

  document.body.appendChild( oScript );

 </script>

js文件载入成功后,json数据会作为参数传入我们定义好的函数,我们可以通过函数来操作得到的json数据。所以jsonp是需要服务器端的页面进行相应的配合的。

<?php
$callback = $_GET['callback'];//得到回调函数名
$data = array('a','b','c');//要返回的数据
echo $callback.'('.json_encode($data).')';//输出

如果你的页面使用jquery,那么通过它封装的方法就能很方便的来进行jsonp操作了

<script type="text/javascript">
    $.getJSON('http://example.com/data.php?callback=?,function(jsondata)'){
        //处理获得的json数据
    });
</script>

jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。

json是理想的数据交换格式,但没办法跨域直接获取,于是就将json包裹(padding)在一个合法的js语句中作为js文件传过去。这就是json和jsonp的区别,json是想要的东西,jsonp是达到这个目的而普遍采用的一种方法,当然最终获得和处理的还是json。所以说json是目的,jsonp只是手段。json总会用到,而jsonp只有在跨域获取数据才会用到。
JSONP的优缺点:

(1)优点:jsonp不受跨域的限制、能够直接访问响应文本、支持在浏览器与服务器间的双向通信、的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;

(2)缺点:首先,JSOP是从其他域中加载代码执行,如果其他域不安全,很可能会在响应中夹带一些恶意代码,而此时唯一的选择只有完全放弃JSONP的调用;其次,我们要确定JSONP请求是否失败并不容易,为此就不得不使用计时器检测指定时间内是否接收到了响应;同时它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。