JavaScript跨域方法汇总

做Web开发经常需要面对跨域问题,跨域问题的根源是浏览器安全中的同源策略,比如说,对于来说:

1.是同源的;
2.https://www.a.com/2.html是不同源的,原因是协议不同;
3.:8080/2.html是不同源的,原因是端口不同;
4.是不同源的,原因是主机不同。

在浏览器中,<script>、<img>、<iframe>和<link>这几个标签是可以加载跨域(非同源)的资源的,并且加载的方式其实相当于一次普通的GET请求,唯一不同的是,为了安全起见,浏览器不允许这种方式下对加载到的资源的读写操作,而只能使用标签本身应当具备的能力(比如脚本执行、样式应用等等)。

最常见的跨域问题是Ajax跨域访问的问题,默认情况下,跨域的URL是无法通过Ajax访问的。这里我记录我所了解到的跨域的方法:

1. 服务器端代理,这没有什么可说的,缺点在于,默认情况下接收Ajax请求的服务端是无法获取到的客户端的IP和UA的。

2. iframe,使用iframe其实相当于开了一个新的网页,具体跨域的方法大致是,域A打开的母页面嵌套一个指向域B的iframe,然后提交数据,完成之后,B的服务端可以:

●返回一个302重定向响应,把结果重新指回A域;
●在此iframe内部再嵌套一个指向A域的iframe。

这两者都最终实现了跨域的调用,这个方法功能上要比下面介绍到的JSONP更强,因为跨域完毕之后DOM操作和互相之间的JavaScript调用都是没有问题的,但是也有一些限制,比如结果要以URL参数传递,这就意味着在结果数据量很大的时候需要分割传递,甚是麻烦;还有一个麻烦是iframe本身带来的,母页面和iframe本身的交互本身就有安全性限制。

3. 利用script标签跨域,这个办法也很常见,script标签是可以加载异域的JavaScript并执行的,通过预先设定好的callback函数来实现和母页面的交互。它有一个大名,叫做JSONP跨域,JSONP是JSON with Padding的略称。它是一个非官方的协议,明明是加载script,为啥和JSON扯上关系呢?原来就是这个callback函数,对它的使用有一个典型的方式,就是通过JSON来传参,即将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。

在互联网上有很多JSONP的服务来提供数据,本质上就是跨域请求,并且在请求URL中指定好callback,比如callback=result,那么在获取到这些数据以后,就会自动调用result函数,并且把这些数据以JSON的形式传进去,例如(搜索“football”):

?v=1.0&q=football&callback=result

使用JQuery来调用就写成:

复制代码 代码如下:


$.getJSON("http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=football&callback=?",function(data){
    //...
});

总的来说,JSONP的跨域方式的局限性在于,只能使用GET请求,并且不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

4. Flash跨域:

它会访问目标网站根目录下面的crossdomain.xml文件,根据文件中的内容来确定是否允许此次跨域访问:

复制代码 代码如下:


<cross-domain-policy>
    <allow-access-from domain="xxx.xxx.com" />
</cross-domain-policy>

5. img标签也可以使用,这也是一种非常常见的方法,功能上面弱一点,只能发送一个get请求,没有什么回调,Google的点击计数就是这样确定的。

6. window.PostMessage,这个算是HTML5新加入的为跨域通讯考虑的机制,只有Firefox 3、Safari 4和IE8及之后的版本支持。使用它向其它窗口发送消息的调用方式如下:

复制代码 代码如下:


otherWindow.postMessage(message, targetOrigin);


在接收的窗口,需要设置一个事件处理函数来接收发过来的消息:

复制代码 代码如下:


window.addEventListener("message", receiveMessage, false);
function receiveMessage(event){
    if (event.origin !== "http://example.org:8080")
        return;
}


注意这里必需要使用消息的origin和source属性来验证发送者的身份,否则会造成XSS漏洞。

7. Access Control

有一些浏览器支持Access-Control-Allow-Origin这样的响应头,比如:

复制代码 代码如下:


header("Access-Control-Allow-Origin: ");


就指定了允许对跨域访问。

8. window.name

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgsdjg.html