1. 程式人生 > >怎樣利用window.name跨域

怎樣利用window.name跨域

1. window.name的性質

window.name有一個奇妙的性質,
頁面如果設定了window.name,那麼在不關閉頁面的情況下,
即使進行了頁面跳轉location.href=...,這個window.name還是會保留。

我們可以在控制檯做一下實驗:

// 開啟必應 https://www.bing.com/
// 保留控制檯log(勾上Preserve log

> window.name
""

> window.name='test';
"test"

> location.href='http://www.google.com';
"http://www.google.com"
Navigated to https://www.google.com/

> window.name
"test"

利用這一點,我們就可以拿到其他域中的資料了。

2. 跨域請求

我們知道,使用iframesrc屬性,可以載入不同域中的網頁,
我們也可以使用$('iframe').contentWindow來拿到iframe中頁面的window物件,
只是這個window物件中可以訪問的屬性是很少的。

> Object.keys($('iframe').contentWindow);
["postMessage", "blur", "focus", "close", "parent", "opener", "top", "length", "frames", "closed", "location", "self", "window"]

訪問其他屬性,會報錯:

Uncaught DOMException: Blocked a frame with origin "..." from accessing a cross-origin frame.

而如果使用iframe載入同域的頁面,訪問$('iframe').contentWindow的屬性是不會報錯的,它就是iframe內頁面的完整的window物件。

3. 整合

利用window.name的性質,我們可以在iframe中載入一個跨域頁面。

這個頁面載入之後,讓它設定自己的window.name
然後再讓它進行當前頁面的跳轉,跳轉到與iframe外的頁面同域的頁面
此時window.name

是不會改變的。

這樣,iframe內外就屬於同一個域了,且window.name還是跨域的頁面所設定的值。

假設我們有3個頁面,
a.com/index.html
a.com/empty.html
b.com/index.html

(1)在a.com/index.html頁面中嵌入一個iframe,設定srcb.com/index.html
(2)b.com/index.html載入後,設定window.name,然後再使用location.href='a.com/empty.html'跳轉到與iframe外頁面同域的頁面中。
(3)在a.com/index.html頁面中,就可以通過$('iframe').contentWindow.name來獲取iframe內頁面a.com/empty.htmlwindow.name值了,而這個值正是b.com/index.html設定的。

注意:
(1)讓iframe內的跨域頁面,在設定了window.name之後,跳轉到與iframe外頁面同域的頁面,這個過程是必須,否則通過$('iframe').contentWindow.name訪問會報跨域錯誤。
(2)實際操作中,我們一般使用一個隱藏的iframe,然後監聽它第二次onload事件,就知道該iframe已經跳到同域頁面了,然後使用$('iframe').contentWindow.name即可。