最近在發(fā)現(xiàn)使用Taobao的時候的一個小細節(jié),于是便萌發(fā)起了寫這篇文章。
當(dāng)我們在 www.taobao.com 中進行登錄之后,然后直接切換到 www.tmall.com 域名下,發(fā)現(xiàn)www.tmall.com首頁的最頂部馬上顯示成了: 您好, andyfaces。 首先,用戶名應(yīng)該是存儲在cookie中的,于是在taobao.com的域名中用 firefox看到用戶名確實是存儲在 cookie, 而tmall.com中沒有存儲該cookie:
可以確定的是對于cookie來說肯定是不允許垮域訪問的。無論是通過JS還是Server端程序來說都是如此,那么tmall.com是如何訪問到taobao.com下的cookie的呢?
于是打開 tmall.com,然后使用firebug來進行調(diào)試,發(fā)現(xiàn)了一條這樣的請求語句,
其頁面的JS代碼為:
<script>
KISSY.getScript("http://www.taobao.com/go/app/tmall/login-api.php?"+Math.random())
</script>
看到這里之后于是也大概知道他如何處理了的,為了確認一下,于是搜索一下 KISSY.getScript 函數(shù)代碼,確實采用了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); }
其原理是通過動態(tài)create js include 動態(tài)加載js,然后為該script節(jié)點bind onload事件或判斷onreadystatechange,其具體細節(jié)可以參考以上 scriptOnload 的函數(shù)的處理。 當(dāng)js加載完成之后 采用回調(diào)方式來執(zhí)行 success 函數(shù)。
為了進一步確實,于是使用 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結(jié)果:
其實大致原理如此,通過在www.taobao.com 的server端提供一個獲取當(dāng)前域下所有cookie的 php的請求地址,然后該php獲取到cookie之后將期并成 js 代碼,也就是以上第二個截圖所看到的。然后再在 tmall 采用 jsonp 的方式跨域加載該 js 代碼,從而實現(xiàn) cookie 的跨域訪問。
聯(lián)系客服