什么是跨域
| URL | 说明 | 是否允许通信 |
|---|---|---|
| http://www./a.js http://www./b.js | 同一域名下 | 允许 |
| http://www./lab/a.js http://www./script/b.js | 同一域名下不同文件夹 | 允许 |
| http://www.:8000/a.js http://www./b.js | 同一域名,不同端口 | 不允许 |
| http://www./a.js https://www./b.js | 同一域名,不同协议 | 不允许 |
| http://www./a.js http://70.32.92.74/b.js | 域名和域名对应ip | 不允许 |
| http://www./a.js http://script./b.js | 主域相同,子域不同 | 不允许 |
| http://www./a.js http:///b.js | 同一域名,不同二级域名(同上) | 不允许(cookie这种情况下也不允许访问) |
| http://www.cnblogs.com/a.js http://www./b.js | 不同域名 | 不允许 |
- 特别注意两点:
- 第一,如果是协议和端口造成的跨域问题“前台”是无能为力的,
- 第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
“URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。
1、document.domain+iframe的设置
document.domain = '';
var ifr = document.createElement('iframe');
ifr.src = 'http://script./b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
var doc = ifr.contentDocument || ifr.contentWindow.document;
// 在这里操纵b.html
alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};document.domain = '';
- 问题:
- 1、安全性,当一个站点(b.)被攻击后,另一个站点(c.)会引起安全漏洞。
- 2、如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。
2、动态创建script
js.onload = js.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
// callback在此处执行
js.onload = js.onreadystatechange = null;
}
};3、利用iframe和location.hash
function startRequest(){
var ifr = document.createElement('iframe');
ifr.style.display = 'none';
ifr.src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';
document.body.appendChild(ifr);
}
function checkHash() {
try {
var data = location.hash ? location.hash.substring(1) : '';
if (console.log) {
console.log('Now the data is '+data);
}
} catch(e) {};
}
setInterval(checkHash, 2000);//模拟一个简单的参数处理操作
switch(location.hash){
case '#paramdo':
callBack();
break;
case '#paramset':
//do something……
break;
}
function callBack(){
try {
parent.location.hash = 'somedata';
} catch (e) {
// ie、chrome的安全机制无法修改parent.location.hash,
// 所以要利用一个中间的cnblogs域下的代理iframe
var ifrproxy = document.createElement('iframe');
ifrproxy.style.display = 'none';
ifrproxy.src = 'http:///test/cscript/cs3.html#somedata'; // 注意该文件在""域下
document.body.appendChild(ifrproxy);
}
}//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值 parent.parent.location.hash = self.location.hash.substring(1);
4、window.name实现的跨域数据传输
5、使用HTML5 postMessage
- otherWindow.postMessage(message, targetOrigin);
- otherWindow: 对接收信息页面的window的引用。可以是页面中iframe的contentWindow属性;window.open的返回值;通过name或下标从window.frames取到的值。
message: 所要发送的数据,string类型。
targetOrigin: 用于限制otherWindow,“*”表示不作限制
<iframe id="ifr" src="/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {
var ifr = document.getElementById('ifr');
var targetOrigin = 'http://'; // 若写成'http:///c/proxy.html'效果一样
// 若写成'http://'就不会执行postMessage了
ifr.contentWindow.postMessage('I was there!', targetOrigin);
};
</script><script type="text/javascript">
window.addEventListener('message', function(event){
// 通过origin属性判断消息来源地址
if (event.origin == 'http://') {
alert(event.data); // 弹出"I was there!"
alert(event.source); // 对、index.html中window对象的引用
// 但由于同源策略,这里event.source不可以访问window对象
}
}, false);
</script>6、利用flash
可以看在Adobe Developer Connection看到更多的跨域代理文件规范:ross-Domain Policy File Specifications、HTTP Headers Blacklist。
















