【js跨域访问的一些解决方案】

5 篇文章 0 订阅
最近的几个需求,都涉及跨域访问,几次查资料下来,根据自己的理解总结了几个常用的解决跨域访问方法:
 
神马是跨域访问?
各位大牛同事,别见笑。之前我就是连跨域访问都不清楚的小白。。。
如果在http://www.a.com中,我们希望使用Ajax来获得http://www.b.com中内容,由于两个站点不是同一个域名,此时就出现了跨域访问问题。
同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法 。在此情况下,不同浏览器处理的方式也
不同:IE的处理是,弹出警告框,提醒用户; FireFox、Chrome等非微软浏览器的统一处理是拒绝访问。

浏览器会禁止的访问情况:

说明

URL

是否允许跨域

1、同一域名下

http://www.a.com/a.js

允许

http://www.a.com/b.js

2、同一域名下不同文件夹

http://www.a.com/a/a.js

允许

http://www.a.com/b/a.js

3、同一域名不同端口

http://www.a.com:8090/a.js

不允许

http://www.a.com/a.js

4、同一域名不同协议

http://www.a.com/a.js

不允许

https://www.a.com/b.js

5、域名和域名对应的IP

http://www.a.com/a.js

不允许

http://172.25.32.219/a.js

6、主域相同,子域不同

http://www.a.com/a.js

不允许

http://kpm.a.com/b.js

7、不同域名

http://www.a.com/a.js

不允许

http://www.b.com/a.js

即域名、协议、端口,三者中若有一个不相同,则会出现跨域问题。


解决方法:

1、设置document.domain属性(适合同一主域下不同子域间的通信)

对于主域相同而子域不同的情况(上述表格6),可以通过修改document的domain属性来解决。由于同源策略认为域和子域隶属于不同的域,那么我们

无法在a.com/a.js中访问kpm.a.com/b.js。可以在a.js中设置document.domain=a.com,此时浏览器就会认为它们处于同一个域下,这样两个文件之

间就可以正常通信了

2、window.name方式(适合单向的数据请求)

window.name属性是一个很特别的属性,当该window的location变化,然后重新加载,name属性可以依然保持不变。所以我们可以在页面 a.html中

用iframe加载b.html,在b.html中用JavaScript把需要传递的数据赋值给window.name,iframe加载完成之后,在a.html修改iframe的地址,将其变成

代理文件proxy.htmlproxy.html与a.html在同一个域名下,可以通信),然后就可以读出window.name的值了(最大支持2M数据量)。

function crossDomain() {
    var data = '';   
    var iframe = document.createElement('iframe');
    iframe.style.display = 'none';   
    document.body.appendChild(iframe);
    var _load = function() {
           try{
                   data = iframe.contentWindow.name;
            }catch(e) {
                    iframe.contentWindow.location= 'http://www.a.com/proxy.html';
            }
            if(iframe.attachEvent) { 
                    iframe.attachEvent('onload', _load);
            } else {
                    iframe.onload = _load;
            }
            iframe.src = 'http://www.b.com/b.html';
        //为不让其他域的js访问name,最后销毁iframe
            iframe.contentWindow.document.write('');
            iframe.contentWindow.close();
            document.body.removeChild(iframe);
        return data;
};

3、动态创建js(只能加载js文件)

script标签本身就可以访问其它域的资源,不受浏览器同源策略的限制,可以通过在页面动态创建script标签,代码如下:

        var script = document.createElement('script');  
        script.src = "XXX";  
        document.body.appendChild(script); 

这样通过动态创建script标签就可以加载其它域的js文件,然后通过本页面就可以调用加载后js文件的函数。缺陷是不能加

载其它域的文档,只能是js文件。

4、使用HTML5的window.postMessage(很酷的新技术)

window.postMessage是HTML5定义的一个很新的方法,使用它可以很方便地进行跨文档消息传输Cross Document Messaging。

语法:

otherWindow.postMessage(message, targetOrigin);
· message:作为postMessage()第一个参数传入的字符串数据。
· targetOrigin:发送消息的文档所在的域,例如" http://www.a.com"
 发送消息方:iframe.contentWindow.postMessage('Hello lynnelv');
 消息接收方:
window.addEventListener("message", function(event) { 
        if (event.origin == " http://www.a.com"){     //确保发送消息的域是已知的域
                processMessage(event.data);    //处理接收到的数据
        }
});
5、JSONP方式
JSONP的原理:src是个特殊的属性,带这个属性的标签,如iframe、script、img都可以跨域。jsonp就是动态创建<script>来调用服务器端的js脚本。
使用:在客户端指定一个回调, 回调的语法为:url?callback=?。此时,服务器生成 的json 数据,将被封装到callbackFunction()中,返回给客户端。
实现代码很简单只需要在ajax请求的时候,指定dataType为jsonp即可:
$.ajax({
    type: 'get',
    async: false,   //注意区别jsonp和ajax实质,一个是动态创建<script>,一个是通过xhr对象操作,jsonp并不支持async
    url: 'www.example.com/demo.phtml?var=test',
    dataType: 'jsonp',
    jsonp: 'cb',   //传递给请求页面获取回调函数的参数名,默认为callback
    jsonCallback: 'handler'   //自定义jsonp的回调函数名,若不指定,则jQuery自动生成 
});



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值