1. 程式人生 > >從淘寶架構之cookie跨域,看網際網路技術發展方向

從淘寶架構之cookie跨域,看網際網路技術發展方向

       最近在發現使用Taobao的時候的一個小細節,於是便萌發起了寫這篇文章。

 當我們在 www.taobao.com 中進行登入之後,然後直接切換到 www.tmall.com 域名下,發現www.tmall.com首頁的最頂部馬上顯示成了: 您好, andyfaces。 首先,使用者名稱應該是儲存在cookie中的,於是在taobao.com的域名中用 firefox看到使用者名稱確實是儲存在 cookie, 而tmall.com中沒有儲存該cookie: 

可以確定的是對於cookie來說肯定是不允許垮域訪問的。無論是通過JS還是Server端程式來說都是如此,那麼tmall.com是如何訪問到taobao.com下的cookie的呢?

於是開啟 tmall.com,然後使用firebug來進行除錯,發現了一條這樣的請求語句, 

其頁面的JS程式碼為:

<script>  
        KISSY.getScript("http://www.taobao.com/go/app/tmall/login-api.php?"+Math.random())  
</script>

看到這裡之後於是也大概知道他如何處理了的,為了確認一下,於是搜尋一下 KISSY.getScript 函式程式碼,確實採用了JS跨域的 JSONP 解決方案:

getScript: function(url, success, charset) {  
    var isCSS = RE_CSS.test(url),  
	node = doc.createElement(isCSS ? 'link' : 'script'),  
	config = success, error, timeout, timer;  

	node.src = url;  
	node.async = true;  

    scriptOnload(node, function() {  
	    if (timer) {  
		timer.cancel();  
		timer = undef;  
	    }  

	    S.isFunction(success) && success.call(node);  

	    // remove script  
	    if (head && node.parentNode) {  
		head.removeChild(node);  
	    }  
	});  
    head.insertBefore(node, head.firstChild);  
}  

其原理是通過動態create js include 動態載入js,然後為該script節點bind onload事件或判斷onreadystatechange,其具體細節可以參考以上 scriptOnload 的函式的處理。 當js載入完成之後 採用回撥方式來執行 success 函式。

為了進一步確實,於是使用 Jquery的 $.getScript 來測試一把,首先在 taobao.com下進行登入成功,然後隨便在本地寫了一個測試頁,通過以下語句:

$.getScript('http://www.taobao.com/go/app/tmall/login-api.php?0.6783450077710154', function(){  
    console.log("the taobao.com cookie object:" + userCookie + " username:" + userCookie._nk_);  
}); 

Firbug結果:

其實大致原理如此,通過在www.taobao.com 的server端提供一個獲取當前域下所有cookie的 php的請求地址,然後該php獲取到cookie之後將期併成 js 程式碼,也就是以上第二個截圖所看到的。然後再在 tmall 採用 jsonp 的方式跨域載入該 js 程式碼,從而實現 cookie 的跨域訪問。