利用jsonp、iframe和location.hash解决跨域问题

页面导航:首页 > 网络编程 > JavaScript > 利用jsonp、iframe和location.hash解决跨域问题

利用jsonp、iframe和location.hash解决跨域问题

来源: 作者: 时间:2016-01-23 10:23 【

几种解决js跨域的方法js的跨域:由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。如下示例:URL 说明

几种解决js跨域的方法

js的跨域:由于同源策略,凡是发送请求url的协议、域名、端口三者之间任意一

与当前页面地址不同即为跨域。如下示例:

 

注意:对于端口和协议的不同,只能通过后台来解决。
解决办法:
1.script标签的形式:jsonp
2.document.domain
3.服务器代理 4.window.name
5.flash
6. 5 postMessage
7. iframe和location.hash

通过jsonp

在js中,我们直接用ajax中XMLHttpRequest对象请求不同域上的数据时,是不可以的,

不能跨域,但是,在页面上引入不同域上的js脚本文件是可以的,jsonp就是利用这个特

性来实现的。
例如,如果有个a.html页面,它里面的代码需要利用ajax获取一个不同域上的json数据

,那么a.html中的代码就可以这样写:

script type="text/javascript">
        function jonpCallBack(data){

        }
    
   <script type="text/javascript" src="http://example.com/data.php?

callback=jonpCallBack"></script>

或者自动创建js加入页面:

 function createJs(sUrl){
            var oScript = document.createElement('script');
            oScript.type='text/javascript';
            oScript.src = sUrl;
            document.getElementsByTagName('head')[0].appentChild(oScript);

        }
        createJs('http://example.com/data.php?callback=jonpCallBack');

js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作

为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。

php代码:

 

最终,输出结果为:jonpCallBack([‘a’,’b’,’c’]);

如果使用jQuery,通过它的封装方法就能很方便的来才操作jsonp了。

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

jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自

动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,

不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用

jsonp的回调函数。

利用iframe和location.hash:

这个方法也可以解决完全跨域情况下的问题,利用location.hash来进行传值。在url:

http://a.com#helloword中的‘#helloworld’就是location.hash,改变hash并不会导

致页面刷新,所以可以利用hash值来进行数据传递,当然数据容量是有限的。假设域名

a.com下的文件cs1.html要和cnblogs.com域名下的cs2.html传递信息,cs1.html首先创

建自动创建一个隐藏的iframe,iframe的src指向cnblogs.com域名下的cs2.html页面,

这时的hash值可以做参数传递用。cs2.html响应请求后再将通过修改cs1.html的hash值

来传递数据(由于两个页面不在同一个域下IE、Chrome不允许修改

parent.location.hash的值,所以要借助于a.com域名下的一个代理iframe;Firefox可

以修改)。同时在cs1.html上加一个定时器,隔一段时间来判断location.hash的值有没

有变化,一点有变化则获取获取hash值。代码如下:
先是a.com下的文件cs1.html文件:

function startRequest(){
    var ifr = document.createElement('iframe');
    ifr.style.display = 'none';
    ifr.src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';
    document.body.appendChild(ifr);
}

function checkHash() {
    try {
        var data = location.hash ? location.hash.substring(1) : '';
        if (console.log) {
            console.log('Now the data is '+data);
        }
    } catch(e) {};
}
setInterval(checkHash, 2000);

cnblogs.com域名下的cs2.html:

//模拟一个简单的参数处理操作
switch(location.hash){
    case '#paramdo':
        callBack();
        break;
    case '#paramset':
        //do something……
        break;
}

function callBack(){
    try {
        parent.location.hash = 'somedata';
    } catch (e) {
        // ie、chrome的安全机制无法修改parent.location.hash,
        // 所以要利用一个中间的cnblogs域下的代理iframe
        var ifrproxy = document.createElement('iframe');
        ifrproxy.style.display = 'none';
        ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata';    // 

注意该文件在"a.com"域下
        document.body.appendChild(ifrproxy);
    }
}

a.com下的域名cs3.html

//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);

当然这样做也存在很多缺点,诸如数据直接暴露在了url中,数据容量和类型都有限等

Tags:

文章评论

最 近 更 新
热 点 排 行
Js与CSS工具
代码转换工具

<