摘要:首先聲明,這里所說(shuō)的根域名,并不是指全球共有臺(tái)根邏輯域名服務(wù)器這句話中的根域名。在本文中,我們將這樣的域名稱為根域名。無(wú)論訪問(wèn)哪個(gè)子站點(diǎn),都要通過(guò)將存放到根域名下。在這種情況下,顯然我們不能認(rèn)為是根域名。比如一個(gè)名為的倉(cāng)庫(kù)。
首先聲明,這里所說(shuō)的“根域名”,并不是指“全球共有13臺(tái)根邏輯域名服務(wù)器”這句話中的“根域名”。而是指某一個(gè)站點(diǎn)的“根域名”。
百度搜索是“www.baidu.com”,百度翻譯的域名是“fanyi.baidu.com”,百度地圖的域名則是“map.baidu.com”。這些域名有共同的部分“baidu.com”。在本文中,我們將“baidu.com”這樣的域名稱為“根域名”。前端同學(xué)應(yīng)該都知道,在“.baidu.com”這一域下的 cookie 可以在其他子站點(diǎn)下拿到(當(dāng)然,前提是端口號(hào)和協(xié)議都保持一致)。
最近開(kāi)發(fā)的過(guò)程中遇上了一個(gè)小問(wèn)題。無(wú)論訪問(wèn)哪個(gè)子站點(diǎn),都要通過(guò) js 將 cookie 存放到根域名下。
一開(kāi)始比較大意,直接拿正則匹配。問(wèn)題是忽略了這世界上還存在“www.xxx.edu.cn”這樣的站點(diǎn)。在這種情況下,顯然我們不能認(rèn)為”edu.cn“是根域名。想在一個(gè)叫“edu.cn”的域下存 cookie?對(duì)不起,瀏覽器做不到。(這句話很重要。)
正則匹配是做不到了。搜索了一下,網(wǎng)上也沒(méi)有什么特別好的解決方案。無(wú)非是枚舉出國(guó)內(nèi)常見(jiàn)的一些頂級(jí)域名,然后再進(jìn)行處理,如下面這個(gè) PHP 的例子:
但如何確保我們枚舉出的例子一定是完全的無(wú)遺漏的呢?不完美,放棄。
PSL接著上 github 上去找例子。倒是發(fā)現(xiàn)了一些解決域名的工具。比如一個(gè)名為 psl 的倉(cāng)庫(kù)。
PSL 是 “Public Suffix List” 的縮寫(xiě),這個(gè)“公共域名后綴列表”項(xiàng)目本來(lái)是供瀏覽器廠商使用的??梢栽L問(wèn)官網(wǎng),另外建議看看這篇《域名小知識(shí):Public Suffix List》。
我搜索到的這個(gè) psl 倉(cāng)庫(kù)正是基于 PSL、使用 js 來(lái)解析域名的。粗略看了下,存放域名的 json 文件有 108 KB。嚇?biāo)懒恕?/p>
另一款叫做 parse-domain 的,光是生成的正則表達(dá)式文件就有 203 KB。
沒(méi)辦法,一個(gè)跑到瀏覽器上的前端腳本,本身不到 1500 行,為了一個(gè)判斷引入上百 KB 的外部依賴,實(shí)在不劃算。
于是只能自己另起爐灶,想想別的辦法。
document.domain首先想到的是 document.domain。在一些需要跨域的場(chǎng)景中,可能會(huì)見(jiàn)到這貨的身影。比如這篇文章 所描述的,“相同主域名不同子域名下的頁(yè)面,可以設(shè)置 document.domain 讓它們同域”。
經(jīng)過(guò)測(cè)試發(fā)現(xiàn),對(duì)于域名c.example.edu.cn下的頁(yè)面,可以執(zhí)行下面這句:
document.domain = "example.edu.cn";
而在 Chrome 下,下面這句則無(wú)法執(zhí)行:
// DOMException document.domain = "edu.cn";
瀏覽器會(huì)拋出DOMException:
1 Uncaught DOMException: Failed to set the "domain" property on "Document": "edu.cn" is not a suffix of "c.example.edu.cn".
IE 也會(huì)報(bào)出“參數(shù)無(wú)效”的錯(cuò)誤;Firefox 下同樣會(huì)拋出錯(cuò)誤:
NS_ERROR_DOM_BAD_DOCUMENT_DOMAIN: Illegal document.domain value
從報(bào)錯(cuò)信息可以看到, DOMException 是可以捕獲到的。那就好辦了。
將域名(或頁(yè)面當(dāng)前的 document.domain) split 成數(shù)據(jù) ["x", "example", "edu", "cn"],從右向左逐次加上一個(gè)元素,每次將單詞使用句點(diǎn)連接并賦值給 document.domain。如果 catch 到錯(cuò)誤,則進(jìn)行下一次操作。一旦賦值成功,即可 break 循環(huán)。
上代碼:
const domain = document.domain; const list = domain.split("."); let len = list.length; let rootDomain = domain; while (len--) { try { document.domain = list.slice(len).join("."); rootDomain = document.domain; break; } catch (e) {} } // 還得恢復(fù)原值,避免產(chǎn)生副作用 document.domain = domain; console.log(rootDomain);
很好,經(jīng)過(guò)簡(jiǎn)單測(cè)試,Chrome、IE 妥妥的。
然而 Firefox 掛了。掛在最后的還原階段。也就是說(shuō),F(xiàn)irefox 允許修改 document.domain,但不允許修改成上一級(jí)之后,再回退到下一級(jí)。
此外(感謝老大),在 Safari 上測(cè)試發(fā)現(xiàn),document.domain = "cn" 不會(huì)報(bào)錯(cuò)!什么鬼?請(qǐng)移步《Webkit下最無(wú)敵的跨大域方案》。
功虧一簣。心好累啊。
Cookie 救火最后想起前面提到的一句,“想在一個(gè)叫 edu.cn 的域下存 cookie?對(duì)不起,瀏覽器做不到?!?/p>
要不咱試試 cookie?動(dòng)手!
道理同上,每次嘗試在手動(dòng)拼接的 domain 下面存 cookie,然后檢查 cookie 是否保存成功。一旦成功,則 break 循環(huán),并清除該 cookie。沒(méi)有副作用,只是多操作幾次 cookie。
換個(gè)思路,總算是解決了。
代碼被我放在了 Github 上。順手貼在這里:
var KEY = "__rT_dM__" + (+new Date()); var R = new RegExp("(^|;)s*" + KEY + "=1"); var Y1970 = (new Date(0)).toUTCString(); module.exports = function getRootDomain() { var domain = document.domain || location.hostname; var list = domain.split("."); var len = list.length; var temp = ""; var temp2 = ""; while (len--) { temp = list.slice(len).join("."); temp2 = KEY + "=1;domain=." + temp; // try to set cookie document.cookie = temp2; if (R.test(document.cookie)) { // clear document.cookie = temp2 + ";expires=" + Y1970; return temp; } } };
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82707.html
摘要:,表單的兩個(gè)常見(jiàn)屬性為填寫(xiě)表單的人提供一個(gè)輸入提示??捎糜谌魏伪韱慰丶?,表示這個(gè)域是必要的,如果不填,則無(wú)法提交表單。,表格,表格由行中的數(shù)據(jù)單元格組成,列隱含地定義在行中。,表格應(yīng)用于表示表格數(shù)據(jù),而不是建立頁(yè)面布局。 1,如何設(shè)計(jì)一個(gè)頁(yè)面 1) 先規(guī)劃好web頁(yè)面的結(jié)構(gòu),首先畫(huà)出一個(gè)草圖,然后創(chuàng)建一個(gè)略圖,最后再寫(xiě)html2) 規(guī)劃頁(yè)面時(shí),先設(shè)計(jì)大的塊元素,再用內(nèi)聯(lián)元素...
摘要:主要內(nèi)容協(xié)議概述狀態(tài)碼報(bào)頭協(xié)議協(xié)議是互聯(lián)網(wǎng)使用最多的協(xié)議,是客戶端和服務(wù)器請(qǐng)求應(yīng)答的標(biāo)準(zhǔn),端口是。一般用于與請(qǐng)求永久移動(dòng)。今后任何新的請(qǐng)求都應(yīng)使用新的代替未修改。 主要內(nèi)容 協(xié)議概述 狀態(tài)碼 報(bào)頭 http協(xié)議 http協(xié)議是互聯(lián)網(wǎng)使用最多的協(xié)議,是客戶端和服務(wù)器請(qǐng)求應(yīng)答的標(biāo)準(zhǔn)TCP,端口是80。用戶通過(guò)http和url統(tǒng)一資源定位符獲取網(wǎng)頁(yè)代碼供瀏覽器渲染。簡(jiǎn)單快速,無(wú)連接無(wú)狀態(tài)...
摘要:幸運(yùn)的是,采用任播技術(shù)架設(shè)鏡像服務(wù)器可解決該問(wèn)題,并使得實(shí)際運(yùn)行的根域名服務(wù)器數(shù)量大大增加。截至年月,全球共有臺(tái)根域名服務(wù)器在運(yùn)行。 前記 從我開(kāi)始學(xué)習(xí)前端我就一直在做著我的個(gè)人簡(jiǎn)歷網(wǎng)站,使用GitHubpPages的預(yù)覽功能進(jìn)行預(yù)覽,但是由于最近我的個(gè)人簡(jiǎn)歷,不停的豐富,圖片增多,而且將css和js文件用webpack打包后變成一個(gè)很大的問(wèn)價(jià),網(wǎng)頁(yè)的加載速度就變的像龜速一樣,所以我決...
閱讀 2067·2021-11-08 13:22
閱讀 2534·2021-09-04 16:40
閱讀 1174·2021-09-03 10:29
閱讀 1741·2019-08-30 15:44
閱讀 2142·2019-08-30 11:13
閱讀 2818·2019-08-29 17:07
閱讀 1991·2019-08-29 14:22
閱讀 1273·2019-08-26 14:00