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

几种解决js跨域的方法

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

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

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 不同域名 不允许

注意:对于端口和协议的不同,只能通过后台来解决。

解决办法:

1.script标签的形式:jsonp

2.document.domain

3.服务器代理 4.window.name

5.flash

6. html5 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>
   <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代码:

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

最终,输出结果为: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中,数据容量和类型都有限等

时间: 2024-10-07 10:24:17

利用jsonp、iframe和location.hash解决跨域问题的相关文章

iframe可通过postMessage解决跨域、跨窗口消息传递

https://www.cnblogs.com/dorothyorsusie/p/6178599.html 1 //iframe传参给父级页面 2 function give_info(){ 3 console.log("触发事件"); 4 window.parent.postMessage(1,'*'); 5 } //接收值window.addEventListener('message',function(e){ var color=e.data; document.getElem

js 利用iframe和location.hash跨域解决办法,java图片上传回调JS函数跨域

奶奶的:折腾了我二天,终于解决了!网上有很多例子. 但跟我的都不太一样,费话不多说了,上图   上代码: IE ,firefix,chrome 测试通过 js :这个主页面,部分代码, function submitUpload(id){ $("#imgSrc" + id +"").attr("alt", "图片上传中--"); var imgID = id; if(id>0){ imgID = 1; } var for

用jQuery与JSONP轻松解决跨域访问的问题【转】

原文地址:http://www.jb51.net/article/46463.htm 好在,有jquery帮忙,跨域问题似乎没那么难缠了.这次也借此机会对跨域问题来给刨根问底,结合实际的开发项目,查阅了相关资料,算是解决了跨域问题..有必要记下来备忘. 跨域的安全限制都是指浏览器端来说的.服务器端是不存在跨域安全限制的,所以通过本机服务器端通过类似httpclient方式完成“跨域访问”的工作,然后在浏览器端用AJAX获取本机服务器端“跨域访问”对应的url.来间接完成跨域访问也是可以的.但很显

非jsonp解决跨域问题

1.服务器端解决跨域问题:配置filter在filter中设置请求头import java.io.IOException; import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servle

用jQuery与JSONP轻松解决跨域访问的问题

时间过得好快,又被拉回js战场时, 跨域问题这个伤疤又开疼了. 好在,有jquery帮忙,跨域问题似乎没那么难缠了.这次也借此机会对跨域问题来给刨根问底,结合实际的开发项目,查阅了相关资料,算是解决了跨域问题..有必要记下来备忘. 跨域的安全限制都是指浏览器端来说的.服务器端是不存在跨域安全限制的,所以通过本机服务器端通过类似httpclient方式完成“跨域访问”的工作,然后在浏览器端用AJAX获取本机服务器端“跨域访问”对应的url.来间接完成跨域访问也是可以的.但很显然开发量比较大,但限制

JSONP解决跨域问题,防止表单重复提交,防止XSS攻击

一.跨域问题:能够正常请求,但是没有办法获取到响应结果 解决方案一:设置请求头,在请求的资源中设置Access-Control-Allow-Origin请求头 //3.设置请求头 response.setHeader("Access-Control-Allow-Origin", "*"); 二.JSONP解决跨域问题 普通的跨域访问问题,浏览器会进行拦截,凡是src属性的都不会拦截 ajax:http://www.a.com:8080/a/AServlet JSON

详解Jquery和AngularJs,Servlet中jsonp解决跨域问题(转)

众所周知,jsonp可以解决跨域问题,下面是我在查阅资料和实际项目使用后的一些总结. Jquery中jsonp的使用 //myUrl = "http://localhost:8090/api/test"; $.ajax({ type:"GET", url:myUrl, dataType:"jsonp", jsonp:"callback", jsonpCallback:"jsonpCallback", suc

利用Filter解决跨域请求的问题

1.为什么出现跨域. 很简单的一句解释,A系统中使用ajax调用B系统中的接口,此时就是一个典型的跨域问题,此时浏览器会出现以下错误信息,此处使用的是chrome浏览器. 错误信息如下: jquery-1.8.0.min.js:3 Failed to load http://localhost:8081/authz/openapi/v1/token: No 'Access-Control-Allow-Origin' header is present on the requested resou

前端解决跨域问题的8种方案(最新最全)

原文:http://www.cnblogs.com/JChen666/p/3399951.html 1.同源策略如下: URL 说明 是否允许通信 http://www.a.com/a.jshttp://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.jshttp://www.a.com/script/b.js 同一域名下不同文件夹 允许 http://www.a.com:8000/a.jshttp://www.a.com/b.js 同一域名,不同端