本文主要描述使用裸域名做網站主域名時,如何用子域名做 cookie-free domains。
看站點優化的文章,很多建議將站點的靜態文件(如圖片、js、css 等)放在一個專門的域名下訪問,由于該域名與主站域名不同,所以瀏覽器就不會把主域名下的 Cookie 傳給該域,減少了網絡開銷,一定程度提高了頁面加載速度,特別是細碎靜態文件特別多的情況下效果顯著。大概這個域就叫著 cookie-free domain 吧。
Yahoo yslow 可以對網頁性能進行評級,其中一個指標就是 “Use cookie-free domains”,描述如下:
When the browser requests a static image and sends cookies with the request, the server ignores the cookies. These cookies are unnecessary network traffic. To workaround this problem, make sure that static components are requested with cookie-free requests by creating a subdomain and hosting them there.
大意是當瀏覽器請求一個靜態圖片并發送 Cookie 時,服務器會忽略 Cookie。Cookie 根本就沒必要通過網絡傳輸。為了解決這個問題,應當創建一個子域并將靜態內存放在上面,以確保靜態內容都是通過 cookie-free 的方式訪問的。
有文章指出,如果主域名使用裸域名(根域名,例如 opoo.org)而靜態內存使用子域名(例如 static.opoo.org)是無法達到 cookie-free 的。因為裸域的 cookie 會被傳遞給子域。即如果在 opoo.org 設置了cookie,那么訪問子域 static.opoo.org 瀏覽器也會發送這個 Cookie,根本達不到 cookie-free 的目的。----筆者則認為這種說法不完全正確。
Cookie 有兩個重要的屬性:domain 和 path。當瀏覽器訪問一個網站時,只有 domain 和 path 都滿足條件時,才會發送相應的 Cookie 到這個網站的服務器。而服務器在要求瀏覽器設置 Cookie 時,也只能設置與當前網站匹配的 domain 屬性。
Cookie domain 屬性的匹配方法,簡單示例如下:
cookie.domain = "opoo.org" 該 Cookie 只能發給域 opoo.org,不能發到子域 www.opoo.org, static.opoo.org 等
cookie.domain = ".opoo.org" 該 Cookie 可以發給域 opoo.org 及其下所有子域,包括 www.opoo.org, static.opoo.org 等
cookie.domain = "www.opoo.org" 該 Cookie 只能發給域 www.opoo.org, 不能發給域 opoo.org 及 static.opoo.org 等
由此可以看出,裸域的 Cookie 會不會污染到子域,主要就在于設置 Cookie 的 domain 屬性值前面的那個“.”。前綴點(leading dot, leading period, dot prefix, whatever..)大致相當于泛域名匹配吧。
關于這個“點”,RFC 6265 和 RFC 2109 描述不完全一致,有興趣的讀者可以翻看原文。
RFC 6265 4.1.2.3 章節
4.1.2.3. The Domain Attribute The Domain attribute specifies those hosts to which the cookie will be sent. For example, if the value of the Domain attribute is "example.com", the user agent will include the cookie in the Cookie header when making HTTP requests to example.com, www.example.com, and www.corp.example.com. (Note that a leading %x2E ("."), if present, is ignored even though that character is not permitted, but a trailing %x2E ("."), if present, will cause the user agent to ignore the attribute.) If the server omits the Domain attribute, the user agent will return the cookie only to the origin server. The user agent will reject cookies unless the Domain attribute specifies a scope for the cookie that would include the origin server. For example, the user agent will accept a cookie with a Domain attribute of "example.com" or of "foo.example.com" from foo.example.com, but the user agent will not accept a cookie with a Domain attribute of "bar.example.com" or of "baz.foo.example.com".
看這意思難道是說有沒有前綴“點”,Cookie 都會傳給子域?沒太讀懂。
但實際測試的效果跟我前面描述是一致的,即不帶“點”的只能傳給本域,不能傳給子域。
讀者可以自行檢驗:用 Chrome 開發人員工具或者 Firebug 觀察 Github.com 和SourceForge.net 網站及其子網站的請求/響應頭信息中的 Cookie 信息。這兩個網站就是伺服在裸域名上的。
關于網站是否使用裸域,個人覺得,.com 的域名要 www 比較好,還可以利用瀏覽器快捷鍵;而 .org, .net 等域名用裸域挺不錯的,簡潔方便。
在基本搞清楚 cookie-free domains,筆者將本站域名換回到裸域,并設置了通過子域名訪問圖片等靜態內容。
WordPress
WordPress 設置的 Cookie domain 本來就是以不帶點的域名開頭的,不需要額外設置。如果伺服在 www.opoo.org 則要修改 wp-config.php 設置 COOKIE_DOMAIN 屬性。
Google 分析
在裸域名使用 Google 分析,需要在 js 代碼中設置 cookieDomain 屬性為 none,否則生成的 Cookie 域將帶前綴點。
1 | _gaq.push([ '_setDomainName' , 'none' ]); |
百度統計
很不幸,暫時沒有發現百度統計代碼中有設置 cookieDomain 的地方,其生成的 Cookie 是帶前綴點的,會引起 Cookie 污染,所以筆者直接刪除了百度統計代碼。
又注:
避免域名污染。 當瀏覽器向服務器請求一個靜態資源時,會先發送同域名下的 cookie,服務器對于這些 cookie 不會做任何處理。因此它們只是在毫無意義的消耗帶寬。所以你應該確保對于靜態內容的請求是無coockie的請求。
如果給 http://126.com 設置了cookie,那么會感染所有子域名, 請求 http://www.126.com/logo.gif或者http://image.126.com/logo.gif 時便會帶上討厭的cookie。
所以要用單獨的域名,以減少請求,提高網頁性能。