利用jsonp、iframe和location.hash解决跨域问题
来源:互联网 发布:公司域名注册查询 编辑:程序博客网 时间:2024/05/07 19:32
几种解决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中,数据容量和类型都有限等
- 利用jsonp、iframe和location.hash解决跨域问题
- 利用iframe和location.hash实现跨域
- 利用location.hash实现跨域iframe自适应高宽
- 通过 iframe 和 location.hash 进行跨域通信
- js 利用iframe和location.hash跨域解决办法,java图片上传回调JS函数跨域
- location.hash实现跨域iframe自适应
- location.hash+iframe 跨域解决方案
- 利用JSONP--解决ajax跨域问题
- 利用JSONP解决AJAX跨域问题的原理
- jQuery中利用JSONP解决AJAX跨域问题
- 使用window.location.hash解决ajax刷新和导航问题
- jsonp解决跨域问题
- jsonp解决跨域问题
- JSONP解决跨域问题
- jsonp解决跨域问题
- jsonp解决跨域问题
- jsonp和java联合使用解决跨域问题
- 解决iframe跨域问题
- 事件处理之二:点击事件监听器的五种写法
- 社説 20150617 福島復興新指針 自立への転換点が示された
- Android 应用中十大常见 UX 错误
- 在word中使用notepad++实现代码的语法高亮
- 调用另一个Activity
- 利用jsonp、iframe和location.hash解决跨域问题
- GitHub项目协作基本步骤
- JAVA学习路线图---(JAVA1234)
- 获取IP地址
- 建立简单的服务器端程序
- Android4.0 以后不允许在主线程进行网络连接
- 线程之一:JAVA线程基础
- 使用DatagramSocket与DatagramPacket传输数据
- 使用nextInt()等接受输入时必须注意换行符的输入