- 原文地址:The headers we don't want
- 原文作者:Andrew Betts
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:Ethan
- 校對者:Hank
如果你想了解更多 http 頭資訊的知識,請關注 5 月 22 號安德魯在倫敦的演講。
http 頭資訊是控制快取和瀏覽器處理web內容的一種重要方式。但很多時候它都被錯誤或冗餘地使用,這不僅沒有達成我們的使用目的,還增加了載入頁面時的執行開銷。這篇 http 頭資訊的系列博文中的第一篇文章,讓我們先來扒一扒那些不必要的 http 頭資訊。
大多數開發者都瞭解一些 HTTP 頭資訊,並利用它去處理內容。如大家熟知的 Content-Type
和 Content-Length
,它們都是通用的。但最近,Content-Security-Policy
和 Strict-Transport-Security
這樣的頭資訊已經開始用於提高安全性,Link rel=preload
用於提高效能。只是極少數網站使用他們,儘管它們被瀏覽器廣泛支援。
與此同時,還有很多以前就有並且灰常受歡迎的頭資訊是不實用的。我們可以使用 HTTP 存檔 來證實這一點。HTTP 存檔 是由 Fastly 贊助並由 Google 運營的專案,每個月使用 WebPageTest 載入 500,000 個網站並進行效能測試,結果公佈在 BigQuery。
在 HTTP 存檔資料中,這裡列出了 30 個最受歡迎的響應頭資訊(基於存檔中大多數網站都處理的頭資訊進行統計的結果),並大致說說它們多有用:
Header name | Requests | Domains | Status |
---|---|---|---|
date | 48779277 | 535621 | Required by protocol |
content-type | 47185627 | 533636 | Usually required by browser |
server | 43057807 | 519663 | Unnecessary |
content-length | 42388435 | 519118 | Useful |
last-modified | 34424562 | 480294 | Useful |
cache-control | 36490878 | 412943 | Useful |
etag | 23620444 | 412370 | Useful |
content-encoding | 16194121 | 409159 | Required for compressed content |
expires | 29869228 | 360311 | Unnecessary |
x-powered-by | 4883204 | 211409 | Unnecessary |
pragma | 7641647 | 188784 | Unnecessary |
x-frame-options | 3670032 | 105846 | Unnecessary |
access-control-allow-origin | 11335681 | 103596 | Useful |
x-content-type-options | 11071560 | 94590 | Useful |
link | 1212329 | 87475 | Useful |
age | 7401415 | 59242 | Useful |
x-cache | 5275343 | 56889 | Unnecessary |
x-xss-protection | 9773906 | 51810 | Useful |
strict-transport-security | 4259121 | 51283 | Useful |
via | 4020117 | 47102 | Unnecessary |
p3p | 8282840 | 44308 | Unnecessary |
expect-ct | 2685280 | 40465 | Useful |
content-language | 334081 | 37927 | Debatable |
x-aspnet-version | 676128 | 33473 | Unnecessary |
access-control-allow-credentials | 2804382 | 30346 | Useful |
x-robots-tag | 179177 | 24911 | Not relevant to browsers |
x-ua-compatible | 489056 | 24811 | Useful |
access-control-allow-methods | 1626129 | 20791 | Useful |
access-control-allow-headers | 1205735 | 19120 | Useful |
我們這裡只關注那些不需要的頭資訊,以及說明為什麼不需要它們、該如何處理。
沒用的資訊(server, x-powered-by, via)
你可能為你伺服器軟體的選擇而驕傲,但是大多數人(使用者)對此並不關心。並且這些頭部資訊可能會導致你的敏感資訊洩漏進而使得你的網站受到攻擊。
Server: apache
X-Powered-By: PHP/5.1.1
Via: 1.1 varnish, 1.1 squid
複製程式碼
RFC7231 標準允許伺服器在響應中包含 Server
頭資訊,識別用於服務內容的伺服器軟體。最常見的是 “apache” 和 “nginx”。雖然它是允許的,也不是強制的,但是對開發者和終端使用者都沒有太多實在意義。然而,它是當今 web 上第三個最流行的 HTTP 響應頭。
X-Powered-By
是沒有在任何標準中定義卻很受歡迎的頭資訊,相似地,通常用於指出 web 伺服器後的應用軟體平臺。常見的值有 “ASP.net”,“PHP” 和 “Express”,實際上它們並不提供任何好處,還佔用空間。
更具爭議的應該是 Via
,當新增到通過其傳遞的代理來識別代理的任何代理的響應時,RFC7230 規定它是必須的。代理主機名的時候他可能是有用的,但更多時候它像是一個通用識別符號,如 “vegur”,“varnish”,或 “squid”。刪除或者不設定這個頭資訊在技術上是違反規範的,但是沒有瀏覽器對它做任何事情,所以如果你想刪除它是沒問題的。
棄用的標準(P3P, Expires, X-Frame-Options)
另一類 http 頭資訊是那些在瀏覽器中有效果的,但不是(或者不再是)達成效果的最佳方式。
P3P: cp="this is not a p3p policy"
Expires: Thu, 01 Dec 1994 16:00:00 GMT
X-Frame-Options: SAMEORIGIN
複製程式碼
P3P
是個讓人好奇的東東。我對它不瞭解,甚至很好奇,它最常見的值居然是 “this is not a p3p policy”。那它是,還是不是啊?
這要追溯到試圖使機器可讀的隱私政策標準化,當時大家對於如何在瀏覽器中顯示資料存在分歧,並且只有一個瀏覽器實現了這個 http 頭資訊 -- IE 瀏覽器。即使在 IE 瀏覽器中,P3P
也不會給使用者帶去任何視覺效果,它只需要在 iframe 中允許訪問第三方cookie。有些網站甚至設定了一個不符合標準的 P3P 規則,比如上面的一個,即使這樣做是不合法律規定的。
不用說,讀取第三方 cookie 通常是不可取的,所以如果你打算不這樣做,你也不需要設定一個 P3P
頭資訊
Expires
受歡迎程度達到了不可思議的狀況,試想下這種情況,Cache-Control
被設定為 20 年後過期。如果 Cache-Control
頭資訊包含 max-age
指令,那麼在相同響應上的任何 Expires
頭資訊將被忽略。但是有大量網站同時設定了這兩個資訊,並且 Expires
頭資訊通常被設定為格林尼治時間 -- Thu, 01 Dec 1994 16:00:00
。很多人這樣做因為他們不希望網站內容被快取和複製,所以就從規範中複製這個例項日期來填充。
實際上我們沒必要這麼做。如果你設定了一個 Expires
頭資訊併為其設定了一個過往的時間,那麼你可以這麼設定,用來取代你之前的做法:
Cache-Control: no-cache, private
複製程式碼
一些稽核你網站的工具會讓你新增一個值為 “SAMEORIGIN” 的 X-Frame-Options
頭資訊。這告訴瀏覽器你拒絕被其他網站誣陷,這也是預防點選攻擊的一種常用手段。
然而,以下更一致的支援和更可靠的行為定義的方式,可以實現同樣的效果:
Content-Security-Policy: frame-ancestors 'self'
複製程式碼
作為頭資訊(csp)的一部分,你還獲得其他好處(稍後會詳細介紹)。所以你現在可能沒有 X-Frame-Options
頭資訊。
除錯資料(X-ASPNet-Version, X-Cache)
令人驚訝的是,一些最常用的頭資訊都沒有任何標準。實際上,這意味著,成千上萬的網站似乎自發地同意以特定的方式使用特定的 http 頭資訊。
X-Cache: HIT
X-Request-ID: 45a336c7-1bd5-4a06-9647-c5aab6d5facf
X-ASPNet-Version: 3.2.32
X-AMZN-RequestID: 0d6e39e2-4ecb-11e8-9c2d-fa7ae01bbebc
複製程式碼
實際上,這些“未知”頭資訊並不是由網站開發人員獨立完成的。它們通常是受使用特定伺服器框架、軟體或特定供應商服務的人為因素的影響而形成的(在此示例中,最後一個頭資訊是常見的 AWS 頭資訊)。
特別地,X-Cache
實際是 Fastly 新增的(其他 CDN 也是這樣做的),其他一些與 Fastly 相關的頭資訊,如X-Cache-Hits
和 X-Served-By
。當啟用除錯時,我們新增更多頭資訊,如 Fastly-Debug-Path
和 Fastly-Debug-TTL
。
這些頭資訊無法被任何瀏覽器識別,刪除它們對網頁渲染沒有任何影響。但是,由於這些標題可能向開發人員提供有用的資訊,因此你或許要保留一些方法來告知開發者。
不能被正確識別(Pragma)
我沒料到會在 2018 年寫一篇關於“Pragma”頭的文章,但根據我們的 HTTP 存檔資料,它居然還排在了第 11 位。早在 1997 年,Pragma 就已經棄用了,它也從來沒有打算成為響應頭 —— 正如所指定的,它只有作為請求的一部分時才有意義。
Pragma: no-cache
複製程式碼
儘管如此,它作為一個響應頭是如此被廣泛使用,以至於一些瀏覽器也能識別它。現在,你的迴應將傳遞一個能識別 Pragma
的快取,而不能識別 Cache-Control
的概率很小。如果你想確保某些東西沒有被快取,你只需要 Cache-Control: no-cache, private
。
非瀏覽器的(X-Robots-Tag)
排名前 30 的頭資訊中有一個是非瀏覽器的頭資訊。X-Robots-Tag
用於對付網路爬蟲,比如 Google 和 Bing 的機器人。因為它對瀏覽器沒有任何意義,所有你可以在需要應對爬蟲的時候才設定這個頭資訊。與此同時帶來的影響,可能是使得測試變得困難,或者是違反了搜尋引擎的服務條款。
Bugs
最後,值得一提的是簡單的錯誤。在一個請求中,Host
頭資訊存在是有道理的,但是如果它出現在響應中就說明很可能你的服務被錯誤地配置(我很想知道這是怎麼產生的)。儘管如此,上文提到的 HTTP 存檔還是有 68 個網域返回了 Host
的頭資訊。
刪除頭資訊
如果你的網站使用了 Fastly 的服務,那麼恭喜你,使用 VCL 是刪去頭資訊是很便捷的。你可能希望將真正有用的除錯資料保留到你的開發團隊中,但將其隱藏在公共使用者中,這很有意義,你可以通過檢測 cookie 或傳進來 HTTP 頭資訊來輕鬆實現:
unset resp.http.Server;
unset resp.http.X-Powered-By;
unset resp.http.X-Generator;
if (!req.http.Cookie:debug && !req.http.Debug) {
unset resp.http.X-Amzn-RequestID;
unset resp.http.X-Cache;
}
複製程式碼
在本系列的下一篇文章中,我將討論設定 HTTP 頭資訊的最佳做法,以及如何啟用它們。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。