您的位置:首页 > Web前端 > JavaScript

js中的几种跨域方法

2017-07-28 21:00 92 查看
js跨域指的是通过js在不同域之间进行数据传输或通讯,例如ajax通信技术,或者通过js获取页面中iframe的数据。只要有任意一个不同,则协议、域名、端口中有任意一个不同,则彼此成为不同的域。

所谓同源是指,域名,协议,端口均相同,不明白没关系,举个栗子:

1)http://www.123.com/index.html 调用 http://www.123.com/server.php (非跨域)

2)http://www.123.com/index.html 调用 http://www.456.com/server.php主域名不同:123/456,跨域)
3)http://abc.123.com/index.html 调用 http://def.123.com/server.php子域名不同:abc/def,跨域)
4)http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php端口不同:8080/8081,跨域)
5)http://www.123.com/index.html 调用 https://www.123.com/server.php协议不同:http/https,跨域)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。

1. 通过window.name来跨域——这个方法最方便

同一个窗口在其生命周期内都共享一个window.name,该窗口的每个页面都能获取并修改window.name属性,页面刷新或者发生页面跳转并不会直接引起window.name的改变。
例如:
a.html中
<script>
window.name="父页面的值";
setTimeout(function(){
window.location="b.html";
},1000);
</script>b.html中
<script>
alert(window.name);//输出“父页面的值”;
</script>a.html页面自动跳转到b.html后弹出窗口显示a页面中设置的window.name

2. 通过document.domain来跨域

浏览器在不同的框架之间能获取到彼此的window对象,但是不能进行js交互操作,也无法获取到window对象的属性和方法,例如无法获取到iframe中的东西。
但是只要把两个页面的document.domain设置成相同的域名,就可以进行js通信了。但是document.domain的设置是有限制的,我们只能把document.domain
设置成自身或者更高一级的父域,
a.html中
<iframe src="http://example.com/b.html" id='ifram' onload="test()"></iframe>
<script>
document.domain="example.com";
function test(){
alert(document.getElementById('iframe').contentWindow);
</script>b.html页面中
<script>
document.domain="example.com";
</script>这样我们就能通过js访问到iframe中的各种对象和属性了。

3. 通过jsonp跨域

原理:不同域的页面可以相互引用js叫本文文件,jsonp就是利用这个特征实现跨域。
比如,有一个a.html页面,他里面的代码需要利用ajax获取一个不同域的json数据,
<script>
function callbackfunction(){
alert(jsondata.length);//处理json数据
}
</script>
<script src="1.php?callback=callbackunction"></script>因为是当做一个js文件来引入,所以1.php返回的必须是一个能执行的js文件,所以这个页面的php代码可能是这样的:
<?php
$callback=$_GET['callback'];//得到回调函数名
$data='["ls1","customername2"]';//json数据
echo $callback . "(" . $json_data . ")";//输出jsonp格式的数据

?>调用dosomething(),则输出2。
如果用jQuery,则可以用下面的代码:
<script>
$.getJSON('1.php?callback=?',function(data){
alert(data.length);
}
</script>callback后面的?会自动解析为后面的回调函数。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通 ajax方法;跨域 话,就会以异步加载js文件的形式来调用jsonp的回调函数。

4. 使用HTML5中的window.postMessage方法来跨域传送数据

无论是同源的还是不同源的,都可以使用window.postMessage(message,targetOrigin) 方法来传送数据。这里的message只能为string对象,第二个参数targetOrigin用来限定接受消息的window对象所在的域,若不限定域,可以使用通配符*。但是该方法不支持IE6和IE7。
示例如下:
<script>
function onLoad(){
var iframe=document.getElementById('iframe');
var win=iframe.contentWindow;
win.postMessage('页面a传来消息','*');
</script>
<iframe id='iframe' src="b.html" onload="onLoad()"></iframe>b.html
<script>
window.onmessage=function(e){
e=e | event;//获取事件对象
alert(e.data);//通过data属性得到传来的消息
}
</script>

5. 利用WebSocket跨域

web sockets是一种浏览器的API,他的目标是在一个单独的持久连接上提供全双工、双向通信。(同源策略对web socket不适用)
web sockets原理:在js创建了一个web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器相应后,建立的连接会使用HTTP升级从HTTP协议交换为web socket协议。
该方法只有在支持web socket协议的服务器上才能正常工作。需要在python环境下安装mod_pywebsocket。
<script>
var ws=new WebSocket("ws://localhost/test.html");//ws:http; wss:https
ws.send("hello world"):
ws.onmessage=function(event){
var data=event.data;
}
</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: