Closed amenzai closed 6 years ago
受同源限制有如下几点:
两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享 Cookie。
// A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html document.domain = 'example.com'; // 现在,A 网页通过脚本设置一个 Cookie。 document.cookie = "test1=hello"; // B 网页就可以读到这个 Cookie。 var allCookie = document.cookie;
服务器也可以在设置 Cookie 的时候,指定 Cookie 的所属域名为一级域名,比如.example.com。
Set-Cookie: key=value; domain=.example.com; path=/
这样的话,二级域名和三级域名不用做任何设置,都可以读取这个Cookie。
iframe窗口之中的脚本,可以获得父窗口和子窗口。但是,只有在同源的情况下,父窗口和子窗口才能通信;如果跨域,就无法拿到对方的DOM。
// 父窗口运行下面的命令,如果iframe窗口不是同源,就会报错。 document.getElementById("myIFrame").contentWindow.document // Uncaught DOMException: Blocked a frame from accessing a cross-origin frame. // 窗口获取主窗口的DOM也会报错。 window.parent.document.body // 报错
这种情况还适用于window.open方法打开的窗口,只要跨域,父窗口与子窗口之间就无法通信。
如果两个窗口一级域名相同,只是二级域名不同,那么设置上一节介绍的document.domain属性,就可以规避同源政策,拿到DOM。
对于完全不同源的网站,目前有两种方法,可以解决跨域窗口的通信问题。
URL的#号后面的部分。如果只是改变片段标识符,页面不会重新刷新。
// 父窗口可以把信息,写入子窗口的片段标识符。 var src = originURL + '#' + data; document.getElementById('myIFrame').src = src; // 子窗口通过监听hashchange事件得到通知。 window.onhashchange = checkMessage; function checkMessage() { var message = window.location.hash; // ... } // 同样的,子窗口也可以改变父窗口的片段标识符。 parent.location.href= target + '#' + hash;
postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即“协议 + 域名 + 端口”。也可以设为*,表示不限制域名,向所有窗口发送。
// 父窗口aaa.com向子窗口bbb.com发消息 var popup = window.open('http://bbb.com', 'title'); popup.postMessage('Hello World!', 'http://bbb.com'); // 子窗口向父窗口发送消息的写法类似。 window.opener.postMessage('Nice to see you', 'http://aaa.com'); // 父窗口和子窗口都可以通过message事件,监听对方的消息。 window.addEventListener('message', function(e) { console.log(e.data); },false);
event对象的几个属性:
window.postMessage,也可以读写其他窗口的 LocalStorage
// 主窗口写入iframe子窗口的localStorage window.onmessage = function(e) { if (e.origin !== 'http://bbb.com') { return; } var payload = JSON.parse(e.data); localStorage.setItem(payload.key, JSON.stringify(payload.data)); }; // 父窗口发送消息的代码如下。 var win = document.getElementsByTagName('iframe')[0].contentWindow; var obj = { name: 'Jack' }; win.postMessage(JSON.stringify({key: 'storage', data: obj}), 'http://bbb.com');
跨域解决:
它的基本思想是,网页通过添加一个 Githubissues.
受同源限制有如下几点:
Cookie
两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享 Cookie。
服务器也可以在设置 Cookie 的时候,指定 Cookie 的所属域名为一级域名,比如.example.com。
这样的话,二级域名和三级域名不用做任何设置,都可以读取这个Cookie。
Iframe
iframe窗口之中的脚本,可以获得父窗口和子窗口。但是,只有在同源的情况下,父窗口和子窗口才能通信;如果跨域,就无法拿到对方的DOM。
这种情况还适用于window.open方法打开的窗口,只要跨域,父窗口与子窗口之间就无法通信。
如果两个窗口一级域名相同,只是二级域名不同,那么设置上一节介绍的document.domain属性,就可以规避同源政策,拿到DOM。
对于完全不同源的网站,目前有两种方法,可以解决跨域窗口的通信问题。
片段识别符
URL的#号后面的部分。如果只是改变片段标识符,页面不会重新刷新。
跨文档通信API(window.postMessage)
postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即“协议 + 域名 + 端口”。也可以设为*,表示不限制域名,向所有窗口发送。
event对象的几个属性:
window.postMessage,也可以读写其他窗口的 LocalStorage
Ajax
跨域解决:
JONP
它的基本思想是,网页通过添加一个 Githubissues.