Contents
  1. 1. 目的
  2. 2. 限制
  3. 3. 规避限制:
    1. 3.1. 一 Cookie
    2. 3.2. 二 iframe
      1. 3.2.1. 1. 片段标识符:
      2. 3.2.2. 2. window.name:
      3. 3.2.3. 3. window.postMessage:
    3. 3.3. 三:Ajax:
    4. 3.4. 四:JSONP:
    5. 3.5. 五:WebSocket:
    6. 3.6. 六:CORS:

目的

目的:保证用户信息的安全,防止窃取数据;
同源: 协议相同, 域名相同, 端口相同;

eg: https://www.wjunw.com
    协议:https://,域名是www.example.com,端口是:80(默认可省略);

限制

1. Cookie, LocalStorage, IndexDB无法获取;  
2. DOM 无法获取;
3. AJAX请求不能发送;

规避限制:

两个网页一级域名相同,只是二级域名不同,可设置document.domain共享 Cookie;

eg:  A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html,
     那么只要设置相同的document.domain,两个网页就可以共享Cookie; document.domain = 'example.com';

    注意,这种方法只适用于 Cookie 和 iframe 窗口;

服务器也可以在设置Cookie的时候,指定Cookie的所属域名为一级域名;

比如.example.com;
Set-Cookie: key=value; domain=.example.com; path=/

二 iframe

如果两个网页不同源,就无法拿到对方的DOM。iframe窗口和window.open方法打开的窗口,它们与父窗口无法通信。
则可以使用以下方法:

1. 片段识别符:(fragment identifier)
2. window.name              
3. 跨文档通信API(Cross-document messaging)

1. 片段标识符:

是指;URL的#号后面的部分; 如果只是改变片段标识符,页面不会重新刷新;

父窗口可以把信息写入子窗口的片段标识符。

document.getElementById('myIFrame').src =  originURL + '#' + data;

子窗口通过监听 hashchange 事件:

window.onhashchange = () => {
    const msg = window.location.hash
}

子窗口也可以改变父窗口的片段标识符:

parent.location.href = target + '#' + hash;

2. window.name:

特点: 无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它;
window.name容量很大,可以放置非常长的字符串;缺点是必须监听子窗口window.name属性的变化,影响网页性能;

3. window.postMessage:

HTML5 API: 跨文档通信(Cross-document messaging);
允许跨窗口通信,不论这两个窗口是否同源;
父窗口

var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');

或: 
var win = document.getElementsByTagName('iframe')[0].contentWindow;
var obj = { name: 'Jack' };
win.postMessage(JSON.stringify({key: 'storage', method: "get"}), "*");
window.onmessage = function(e) {
if (e.origin != 'http://aaa.com') return;
console.log(JSON.parse(e.data).name);
};

子窗口

window.opener.postMessage('Nice to see you', 'http://aaa.com');
或 window.parent.postMessage('Nice to see you', 'http://aaa.com');

父窗口和子窗口都可以通过message事件,监听对方的消息:

window.addEventListener('message', function(event) {
// event.source:发送消息的窗口
// event.origin: 消息发向的网址
// event.data: 消息内容
console.log(event.data);
},false);

子窗口通过event.source属性引用父窗口,然后发送消息:

window.addEventListener('message', function(event){
    *,表示不限制域名,向所有窗口发送
event.source.postMessage('Nice to see you!', '*');
});

三:Ajax:

AJAX请求只能发给同源的网址;
规避方法:

1.服务器代理
2.JSONP
3.WebSocket
4.CORS

四:JSONP:

网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来;

五:WebSocket:

WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

六:CORS:

CORS需要浏览器和服务器同时支持;
CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求;
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

Contents
  1. 1. 目的
  2. 2. 限制
  3. 3. 规避限制:
    1. 3.1. 一 Cookie
    2. 3.2. 二 iframe
      1. 3.2.1. 1. 片段标识符:
      2. 3.2.2. 2. window.name:
      3. 3.2.3. 3. window.postMessage:
    3. 3.3. 三:Ajax:
    4. 3.4. 四:JSONP:
    5. 3.5. 五:WebSocket:
    6. 3.6. 六:CORS: