一、
window.postMessage()。
MDN上有详细的实例代码。以下是一个简单实例。
发送方代码
var con = document . getElementsByTagName ( 'iframe' )[ 0 ]. contentWindow ;con . postMessage ( 'hello' , 'http://192.168.110.2' );
接收方代码
window . addEventListener ( 'message' , receive , false );function receive ( event ){var origin = event . origin || event . originalEvent . origin ;if ( origin !== "http://192.168.110.2" )return ;alert ( event . data ); //简单处理}
上述代码中,关键部分是发送方需要获取到接收方窗口的引用,这意味着接收方窗口必须在你的浏览器上打开着,而且是加载完毕的,发送方包含一个data(数据)和origin(接收方的协议加ip,端口号与协议默认端口不符的话就需要加上它)。接收方window为message操作类型绑定一个函数,安全性就体现在这个函数里了,先判断是不是正确的发送方,再处理消息。
实际写demo的时候注意到了以下两点:1、接受消息的页面如果没有加载完,那么就不会有反馈,所以用window.open需要待其加载完毕再发送消息。2、发送对象类型是window,如果是iframe标签,则对象为document.getElementsByTagName("iframe")[0].contentWindow,或者window.frames[0]。
二、jsonp
加载js代码的标签script有src属性,和其他标签的src一样,它也是可以跨域的。jsonp跟一个普通ajax的get请求效果差不多,只是写法不太一样,但是却可以跨域,这就体现与ajax的不同了。几种方法中,似乎就这种应用最普遍了。
这里的原理也比较简单,新建一个script脚本,src为一个普通get请求,请求的内容就是一个函数和数据(类似这种形式,hello(data);),这里的hello需要作为参数传递过去,而且hello函数声明已经事先写好了。部分代码如下:
< body >< p >原始页面内容</ p >< button onclick = "helloworld()" > hello </ button ></ body >< script type = "text/javascript" >function helloworld (){var script = document . createElement ( 'script' );var url0 = 'http://192.168.193.88/scdbackup/test0.php?callback=hello' ;script . setAttribute ( 'src' , url0 );document . body . appendChild ( script );}function hello ( data ){document . getElementsByTagName ( 'p' )[ 0 ]. innerHTML = data . message ;}</ script >
上述代码中,test0.php中定义的返回数据类型为json,类似于这种形式
{message:'hello'}。所以点击按钮后,标签p的内容会被替换为hello。
三、CORS
cross origin resources sharing---跨域资源共享,即设置Access-Control-Allow-Origin。Ubuntu下的apache2找不到配置headers_module的地方,真是醉人的配置文件。一般情况下,这玩意是默认开启的,只需要找到<Directory />,加上Header set Access-Control-Allow-Origin *就能让任何其他域都能访问到,如果想要限定某个ip,只需把*替换为某个ip就好。php中,只要在需要被其他域访问到的php文件开头中加上header("Access-Control-Allow-Origin:*"); 即可。
服务器和php随便配置一项即可使用CORS,而使用CORS的方法则与ajax一毛一样,需要注意的是url要带上协议。
四、window.name
这是个古老的方法。主要流程就是设置一个iframe,src设为跨域请求数据地址,onload的时候获取window.name,再将src改成本域下某个文件,导致再次onload,此时获取name值处理即可。处理完了之后,可以删除这个iframe,防止被其他页面读取。简单代码如下:
<body>
<p>原始页面内容</p>
<button onclick="helloworld()"> hello</button>
</body>
<script type="text/javascript">
function helloworld(){
var ifr = document.createElement('iframe');
ifr.style.display = 'none';
ifr.src = 'http://192.168.193.88/test1.php';
ifr.onload = function(){
ifr.onload = function(){
document.getElementsByTagName('p')[0].innerHTML = ifr.contentWindow.name;
document.body.removeChild(ifr);
}
ifr.src = 'http://192.168.193.1/test.php';
}
document.body.appendChild(ifr);
}
</script>
另外还有一种方法是
document.domain+iframe的设置,不过这是主要针对主域相同而子域不同的跨域请求,使用范围不是很广就不提了。