不嚴格的同源策略—跨文檔消息
前言
以前在 同源策略中提過3種不嚴格的同源策略,今天就來細說其中的一種—跨文檔消息。
跨文檔消息
瀏覽器允許不同文檔之間傳遞消息,而不管其源是否相同。假如現在這裏有兩個窗口,窗口a和窗口b,它們現在是不同源的。此時a可以調用postMessage方法傳遞消息時間,b可以調用onmessage方法來接收,雖然此時a和b還是不能互相訪問,但是也可以實現安全的消息通訊了。
步驟
1.首先打開一個窗口(https://www.bilibili.com/)要注意這裏的url別被代理了,比如打開http://baidu.com,會被代理到https://baidu.com,這個時候協議和端口都改變了,到後面的步驟源肯定就不一樣。
2.使用window.open打開一個新窗口(https://www.baidu.com),並加上onmessage的監聽方法。
let URL = 'https://www.baidu.com';
let target = window.open(URL);
window.onmessage = (e)=>{
if(null != e){
if(null != e.origin && e.origin == 'https://www.baidu.com'){
let data = e.data;
alert(data);
}
}
}
3.在打開的新窗口加上onmessage的監聽方法並判斷消息的來源,發現消息來源正確後再發送收到消息的指令。
window.addEventListener('message',(e)=>{
if(null != e){
if(null != e.origin && e.origin == 'https://www.bilibili.com'){
let source = e.source;
let data = e.data;
source.postMessage('收到信息,內容是:'+data,e.origin);
}
}
})
4.在第一個窗口(https://www.bilibili.com/)發送消息。
target.postMessage('這是發送的信息',URL);
5.如果到此時步驟全部正確,第一個窗口(https://www.bilibili.com/)會出現彈框。
按照1~5的步驟,最終的流程圖應該是這樣的:
窗口A打開了窗口B,窗口B調用了onmessage監聽了origin,如果來源正確就會調用postMessage發送消息給發消息給自己的這條消息的來源(也就是窗口A),窗口A也調用了onmessage監聽了origin,如果正確就彈框(這一步在流程圖中沒表現出來),所以窗口A調用了postMessage方法向窗口B發送消息的時候就產生了鏈式反應。