原文:網站架設 research.microsoft.com/~helenw/papers/subspace.pdfwindow.name 傳輸技術,原本是 Thomas Frank 用於解決 cookie 的網頁設計一些劣勢(每個域名 4 x 20 Kb 的網頁設計限制、數據只能是字符串、設置和獲取 cookie 語法的網頁設計複雜等等)而發明的網頁設計(詳細見原文:《Session variables without cookies》),後來 Kris Zyp 在此方法的網頁設計基礎上強化了 window.name 傳輸 ,並引入到了 Dojo (dojox.io.windowName),用來解決跨域數據傳輸問題。window.name 的網頁設計美妙之處:
name 值在不同的網頁設計頁面(甚至不同域名)加載後依舊存在,並且可以支持非常長的網頁設計 name 值(2MB)。window.name 傳輸技術的網頁設計基本原理和步驟為:name 在瀏覽器環境中是一個全局/window對象的網頁設計屬性,且當在 frame 中加載新頁面時,name 的網頁設計屬性值依舊保持不變。通過在 iframe 中加載一個資源,該目標頁面將設置 frame 的網頁設計 name 屬性。此 name 屬性值可被獲取到,以訪問 Web 服務發送的網頁設計信息。但 name 屬性僅對相同域名的網頁設計 frame 可訪問。這意味著為了訪問 name 屬性,當遠程 Web 服務頁面被加載後,必須導航 frame 回到原始域。同源策略依舊防止其他 frame 訪問 name 屬性。一旦 name 屬性獲得,銷毀 frame 。在最頂層,name 屬性是不安全的網頁設計,對於所有後續頁面,設置在 name 屬性中的網頁設計任何信息都是可獲得的網頁設計。然而 windowName 模塊總是在一個 iframe 中加載資源,並且一旦獲取到數據,或者當你在最頂層瀏覽了一個新頁面,這個 iframe 將被銷毀,所以其他頁面永遠訪問不到 window.name 屬性。基本實現代碼,基於 YUI,源自 克軍寫的網頁設計樣例: 程序代碼(function(){ var YUD = YAHOO.util.Dom, YUE = YAHOO.util.Event; dataRequest = { _doc: document, cfg: { proxyUrl: 'proxy.html' } }; dataRequest.send = function(sUrl, fnCallBack){ if(!sUrl || typeof sUrl !== 'string'){ return; } sUrl += (sUrl.indexOf('?') > 0 ? '&' : '?') + 'windowname=true'; var frame = this._doc.createElement('iframe'), state = 0, self = this; this._doc.body.appendChild(frame); frame.style.display = 'none'; var clear = function(){ try{ frame.contentWindow.document.write(''); frame.contentWindow.close(); self._doc.body.removeChild(frame); }catch(e){} }; var getData = function(){ try{ var da = frame.contentWindow.name; }catch(e){} clear(); if(fnCallBack && typeof fnCallBack === 'function'){ fnCallBack(da); } }; YUE.on(frame, 'load', function(){ if(state === 1){ getData(); } else if(state === 0){ state = 1; frame.contentWindow.location = self.cfg.proxyUrl; } }); frame.src = sUrl; };})();
Web 服務器如何提供 window.name 數據為了讓 Web 服務器實現 window.name,服務器應該只尋找請求中是否包含 windowname 參數。如果包含了 windowname 參數,服務器應該返回一個設置了 window.name 字符串值的網頁設計 HTML 文檔,回應此請求並傳送到客戶端。例如:網站架設 www.planabc.net/getdata.html?windowname=true如果服務器想用 Hello 響應客服端,它應該返回一個 HTML 頁面: 程序代碼<html> <script type="text/javascript"> window.name="Hello"; </script></html>同樣也可以轉換為 JSON 數據: 程序代碼<html> <script type="text/javascript"> window.name='{"foo":"bar"}'; </script></html>如果你手動創建資源,書寫大量的網頁設計多行的網頁設計 JSON 對像為一個引用的網頁設計字符串應該是比較困難的網頁設計並且易於出錯的網頁設計。可以使用這樣的網頁設計 HTML 樣例簡單的網頁設計創建 JSON 數據,將會轉換為一個 JSON 字符串而無需手動轉義 JSON 為字符串: 程序代碼<html> <script type="\'text/javascript\'"> window.name = document.getElementsByTagName("script")[0].innerHTML.match(/temp\s*=([\w\W]*)/)[1]; temp= { foo:"bar", // put json data here baz:"foo" } </script></html>同樣的網頁設計,如果你想傳遞 HTML/XML 數據,這裡有一個樣例實現,而無需手動將這些數據轉換成字符串: 程序代碼<html> <body> <p id="content"> some <strong>html/xml-style</strong>data </p> </body> <script type="text/javascript"> window.name = document.getElementById("content").innerHTML; </script></html>window.name 傳輸技術相比其他的網頁設計跨域傳輸的網頁設計一些優勢:
- 它是安全的網頁設計。也就是說,它和其他的網頁設計基於安全傳輸的網頁設計 frame 一樣安全,例如 Fragment Identifier messaging (FIM)和 Subspace。(I)Frames 也有他們自己的網頁設計安全問題,由於 frame 可以改變其他 frame 的網頁設計 location,但是這個是非常不同的網頁設計安全溢出,通常不太嚴重。
- 它比 FIM 更快,因為它不用處理小數據包大小的網頁設計 Fragment Identifier ,並且它不會有更多的網頁設計 IE 上的網頁設計「機關鎗」聲音效果。它也比 Subspace 快,Subspace 需要加載兩個 Iframe 和兩個本地的網頁設計 HTML 文件來處理一個請求。window.name 僅需要一個 Iframe 和一個本地文件。
- 它比 FIM 和 Subspace 更簡單和安全。FIM 稍微複雜,而 Subspace 非常複雜。Subspace 也有一些額外的網頁設計限制和安裝要求,如預先聲明所有的網頁設計目標主機和擁有針對若幹不同特殊主機的網頁設計 DNS 入口。window.name 非常簡單和容易使用。
- 它不需要任何插件(比如 Flash)或者替代技術(例如 Java)。