Javascript 跨域
2015-07-23 11:34
831 查看
JS跨域是指通过JS在不同的域之间进行数据传输或通信,比如用AJAX向一个不同的域请求数据,或者通过JS获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。
不同环境下JS的通信:
总结了一下,常见的跨域方法有一下几种:
1、document.domain
对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。
具体的做法是可以在http://www.a.com/a.html和http://script.a.com/b.html两个文件中分别加上document.domain = ‘a.com’;然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以“交互”了。
http://www.a.com/a.html
http://script.a.com/b.html
存在的问题:
一、安全性,当一个站点(script.a.com)被攻击后,另一个站点(www.a.com)会引起安全漏洞。
二、如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。
2、动态创建script
虽然浏览器默认禁止了跨域访问,但并不禁止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function(包括操作cookie、Dom等等)。
根据这一点,可以方便地通过创建script节点的方法来实现完全跨域的通信。
3、JSONP(JSON with Padding)
JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。
在JS中,通过<script>可以在页面上引入不同域上的JS脚本文件,jsonp正是利用这个特性来实现的。
前端:
服务器端:
JSONP by jQuery
jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。
$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载JS文件的形式来调用jsonp的回调函数
JSONP的优点是:
它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,不需要XMLHttpRequest或ActiveX的支持。
JSONP的缺点则是:
它只支持GET请求而不支持POST等其它类型的HTTP请求;
它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
4、window.name
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的。
每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
实现跨域需要3个文件:
a.com/app.html:应用页面。
a.com/proxy.html:代理文件,一般是一个没有任何内容的html文件,需要和应用页面在同一域下。
b.com/data.html:应用页面需要获取数据的页面,可称为数据页面。
a.com/app.html
b.com/data.html
特点:
frame的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。
5、HTML5 window.postMessage
window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源。
目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
a.com/index.html
b.com/index.html
6、跨域资源共享(CORS)
CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。
CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。
跨域方法:
注意:
需要服务器和浏览器的支持
例如PHP的响应页面顶端添加如下代码:
表示接受来自a.com的跨域请求,"*"表示接受所有跨域请求
总结不同跨域方法所使用的途径:
其他跨域方法:
1. flash (YUI IO)
2. 代理服务器
不同环境下JS的通信:
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 | 同一域名,不同二级域名 | 不允许 |
http://www.cnblogs.com/a.js http://www.a.com/b.js | 不同域名 | 不允许 |
1、document.domain
对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。
具体的做法是可以在http://www.a.com/a.html和http://script.a.com/b.html两个文件中分别加上document.domain = ‘a.com’;然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以“交互”了。
http://www.a.com/a.html
document.domain = 'a.com'; var ifr = document.createElement('iframe'); ifr.src = 'http://script.a.com/b.html'; ifr.style.display = 'none'; document.body.appendChild(ifr); ifr.onload = function(){ var doc = ifr.contentDocument || ifr.contentWindow.document; // 在这里操纵b.html,调用函数使用ifr.contentWindow.funcName console.log(doc); };
http://script.a.com/b.html
document.domain = 'a.com';
存在的问题:
一、安全性,当一个站点(script.a.com)被攻击后,另一个站点(www.a.com)会引起安全漏洞。
二、如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。
2、动态创建script
虽然浏览器默认禁止了跨域访问,但并不禁止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function(包括操作cookie、Dom等等)。
根据这一点,可以方便地通过创建script节点的方法来实现完全跨域的通信。
3、JSONP(JSON with Padding)
JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。
在JS中,通过<script>可以在页面上引入不同域上的JS脚本文件,jsonp正是利用这个特性来实现的。
前端:
<script type="text/javascript"> function dosomething(jsondata){ //处理获得的json数据 } </script> <script src="http://a.com/data.php?callback=dosomething"> </script>
服务器端:
<?php $callback = $_GET['callback'];//得到回调函数名 $data = array('a','b','c');//要返回的数据 echo $callback.'('.json_encode($data).')'; //输出dosomething(['a','b','c']) ?>
JSONP by jQuery
<script type="text/javascript"> $.getJSON('http://a.com/data.php?callback=?',function(jsondata){ //处理获得的json数据 }); </script>
jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。
$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载JS文件的形式来调用jsonp的回调函数
JSONP的优点是:
它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,不需要XMLHttpRequest或ActiveX的支持。
JSONP的缺点则是:
它只支持GET请求而不支持POST等其它类型的HTTP请求;
它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
4、window.name
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的。
每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
实现跨域需要3个文件:
a.com/app.html:应用页面。
a.com/proxy.html:代理文件,一般是一个没有任何内容的html文件,需要和应用页面在同一域下。
b.com/data.html:应用页面需要获取数据的页面,可称为数据页面。
a.com/app.html
<iframe id="data" src="http://b.com/data.html" style="display:none;" onload="getData()"> </iframe> <script> function getData() { var iframe = document.getElementById('data'); iframe.onload = function () { var data = iframe.contentWindow.name; console.log(data); } iframe.src = 'http://a.com/proxy.html'; } </script>
b.com/data.html
<script type="text/javascript"> window.name = 'data'; // 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右 </script>
特点:
frame的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。
5、HTML5 window.postMessage
window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源。
目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
postMessage(); otherWindow.postMessage(message, targetOrigin); //otherWindow: 对接收信息页面的window的引用。可以是页面中iframe的contentWindow属性; //message: 所要发送的数据,string类型。 //targetOrigin: 用于限制otherWindow,“*”表示不作限制
a.com/index.html
<iframe id="ifr" src="b.com/index.html"></iframe> <script type="text/javascript"> window.onload = function() { var ifr = document.getElementById('ifr'); var targetOrigin = 'http://b.com'; // 若写成'http://c.com'就不会执行postMessage了 ifr.contentWindow.postMessage('I was there!', targetOrigin); }; </script>
b.com/index.html
<script type="text/javascript"> window.addEventListener('message', function(event){ // 通过origin属性判断消息来源地址 if (event.origin == 'http://a.com') { alert(event.data); // 弹出"I was there!" alert(event.source); // 对a.com、index.html中window对象的引用 // 但由于同源策略,这里event.source不可以访问window对象 } }, false); </script>
6、跨域资源共享(CORS)
CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。
CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。
跨域方法:
<script type="text/javascript"> var xhr = new XMLHttpRequest(); xhr.open("GET", "http://b.com/new/",true); xhr.send(); </script>
注意:
需要服务器和浏览器的支持
例如PHP的响应页面顶端添加如下代码:
header("Access-Control-Allow-Origin:http://a.com");
表示接受来自a.com的跨域请求,"*"表示接受所有跨域请求
总结不同跨域方法所使用的途径:
跨域方法 | iframe | script | other |
window.domain | √ | ||
动态<script> | √ | ||
JSONP | √ | ||
window.name | √ | ||
window.postMessage | √ | ||
CORS | √ |
1. flash (YUI IO)
2. 代理服务器
![](http://images0.cnblogs.com/blog2015/630183/201507/231133148038484.jpg)
相关文章推荐
- iframe替换form的js方法
- js 事件委托
- Javascript闭包(Closure)
- 一些javascript常用方法
- js日期方法
- jsp自定义标签库总结
- 201507231056_《JavaScript——事件脚本的添加和删除代码》
- JavaScript 图片的上传前预览(兼容所有浏览器)
- js带箭头左右翻动控制
- js获取url传递参数
- 关于js的总结
- 如何克服 JavaScript 框架疲劳?
- JavaScript js无间断滚动效果 scrollLeft方法 使用模板
- jsp怎样实现动态表格
- 理解JS面向对象
- 高性能JavaScript 循环语句和流程控制
- 常用正则表达式
- javascript添加/删除 对象属性和方法
- Extjs4中up()和down()的用法
- js页面跳转