跨域
js跨域是因为同源策略导致的。解决方法有:
- 图像Ping:使用<img>标签,因为网页可以从任何网页中加载图片,而不用担心跨域。请求数据通过字符串形式发送,而响应可以是任何内容。这种方法,1)只能发送get请求。2)浏览器无法获取响应数据。3)只适用于浏览器与服务器之间的单向通信
- JSONP:通过动态<script>元素使用,使用时为src指定一个跨域url。有两部分:1)回调函数:响应到来时在页面中使用;2)数据:传入回调函数中的JSON数据
- 后台代理方法:将后台作为代理,每次对其它域的请求转交给本域的后台,本域的后台通过模拟http请求去访问其它域,再将返回的结果返回给前台
- 设置document.domain:只适用于主域相同子域不同
- 使用window.name:+iframe。应用页面创建iframe,src指向数据页面;数据页面把数据附加到window.name上;应用界面监听iframe的onload事件,在此事件中设置这个iframe的src指向本地域的代理文件;获取数据后销毁iframe
- 使用html5新方法:window.postMessage(message, targetOrigin)
首先我们要简单了解下window.name和iframe的相关知识。 iframe 是html的一个标签,可以在网页中创建内联框架,有个src属性(指向文件地址,html、php等)可以选择内联框架的内容,可以看个例子( 猛戳这里 ),大概了解下就行了。 window.name (一般在js代码里出现)的值不是一个普通的全局变量,而是当前窗口的名字,这里要注意的是每个iframe都有包裹它的window,而这个window是top window的子窗口,而它自然也有window.name的属性, window.name属性的神奇之处在于name 值在不同的页面(甚至不同域名)加载后依旧存在(如果没修改则值不会变化),并且可以支持非常长的 name 值(2MB)。
跨域解决方案似乎可以呼之欲出了,假设index.html页面请求远端服务器的数据,我们在该页面下新建一个iframe标签,该iframe的src属性指向服务器文件地址(利用iframe标签的跨域能力),服务器文件里设置好window.name的值(也就是该iframe的contentWindow的name值),然后在index.html里读取该iframe的window.name值,一切似乎水到渠成,代码如下:

提示啥协议、主机、端口三者要一致,这不是赤裸裸地告诉你跨域了么!为什么会这样,因为规定如果index.html页面和和该页面里的iframe框架的src如果不同源,则也无法操作框架里的任何东西,所以就取不到iframe框架的name值了,告诉你我们不是一家的,你也休想得到我这里的数据。既然要同源,那就换个src去指,前面说了无论怎样加载window.name值都不会变化,于是我们在index.html相同目录下,新建了个proxy.html的空页面,修改代码如下:

修改后代码如下:

利用window.postMessage()实现跨域消息传递
这个功能实现也非常简单主要包括接受信息的”message”事件和发送消息的”postMessage”方法。


完整程序发送程序
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>42度空间-window.postMessage()跨域消息传递</title>
</head>
<body>
<div>
<input id="text" type="text" value="42度空间" />
<button id="send" >发送消息</button>
</div>
<iframe id="receiver" src="http://res.42du.cn/static/html/receiver.html" width="500" height="60">
<p>你的浏览器不支持IFrame。</p>
</iframe>
<script>
window.onload = function() {
var receiver = document.getElementById('receiver').contentWindow;
var btn = document.getElementById('send');
btn.addEventListener('click', function (e) {
e.preventDefault();
var val = document.getElementById('text').value;
receiver.postMessage("Hello "+val+"!", "http://res.42du.cn");
});
}
</script>
</body>
</html>
完整程序接受程序
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>42度空间-从www.42du.cn接收消息</title>
</head>
<body>
<div id="message">
Hello World!
</div>
<script>
window.onload = function() {
var messageEle = document.getElementById('message');
window.addEventListener('message', function (e) {
alert(e.origin);
if (e.origin !== "http://www.42du.cn") {
return;
}
messageEle.innerHTML = "从"+ e.origin +"收到消息: " + e.data;
});
}
</script>
</body>
</html>
浙公网安备 33010602011771号