js中的几种跨域方法

来源:互联网 发布:灰鸽子远程控制源码 编辑:程序博客网 时间:2024/05/16 08:19

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>











原创粉丝点击