每日前端夜話0xCC
每日前端夜話,陪你聊前端。
每天晚上18:00準時推送。
正文共:1170 字
預計閱讀時間:5 分鐘
作者:Nic Raboy
翻譯:瘋狂的技術宅
來源:thepolyglotdeveloper

最近,我一直在玩 Netlify (https://www.netlify.com/),結果我對内容傳遞網絡(CDN)常見的緩存政策越來越熟悉。有一種将 ETag辨別符用于 Web 資源的政策。
簡而言之,ETag 辨別符是一個值,通常是一個散列,代表特定 Web 資源的版本。該資源與 ETag 值一起緩存在浏覽器中,并且伺服器會在确定特定的緩存資源是否已更改時使用該值。
我們将探索怎樣通過簡單的 cURL 請求用 ETag 辨別符模拟浏覽器發出的請求,而是。
首先,我們将請求資源:
1$ curl -I https://www.thepolyglotdeveloper.com/css/custom.min.css
2
3HTTP/2 200
4accept-ranges: bytes
5cache-control: public, max-age=0, must-revalidate
6content-length: 7328
7content-type: text/css; charset=UTF-8
8date: Wed, 04 Sep 2019 00:41:04 GMT
9strict-transport-security: max-age=31536000
10etag: "018b8b0ecb632aab770af328f043b119-ssl"
11age: 0
12server: Netlify
13x-nf-request-id: 65a8e1aa-03a0-4b6c-9f46-51aba795ad83-921013
複制
在上述請求中,我僅從響應中請求了标頭資訊。對于本文,響應體回複的内容對我們而言并不重要。
注意
cache-control
和
etag
标頭以及響應代碼。
在 Netlify 下,
cache-control
标頭告訴浏覽器緩存資源,但也不信任緩存。這樣做是為了使用戶端始終嘗試擷取最新資源。
etag
标頭代表資源的版本,并随将來的請求一起發送。如果伺服器回複說兩次請求之間的
etag
沒有改變,則響應将會帶有 304 代碼,進而将使用緩存的資源。
是以,讓我們用 cURL 檢查一下資源是否已進行了更改:
1$ curl -I -H 'If-None-Match: "018b8b0ecb632aab770af328f043b119-ssl"' https://www.thepolyglotdeveloper.com/css/custom.min.css
2
3HTTP/2 304
4date: Wed, 04 Sep 2019 00:53:24 GMT
5etag: "018b8b0ecb632aab770af328f043b119-ssl"
6cache-control: public, max-age=0, must-revalidate
7server: Netlify
8x-nf-request-id: eca29310-c9bf-4742-87e1-3412e8852381-2165939
複制
對相同資源的新請求,将包含
If-None-Match
标頭,其值為前一個請求的
etag
哈希。
注意,這次響應狀态代碼為預期的 304。如果 etag 不同,則使用新的 etag 哈希産生 200 響應。
與壓縮的緩存資源進行互動
如果檢視浏覽器的網絡檢查器,您可能會注意到資源的
etag
哈希值附加了
-df
值。例如對于相同的資源,我的浏覽器顯示以下内容:
1018b8b0ecb632aab770af328f043b119-ssl-df
複制
雖然相似,但與之前的 cURL 請求傳回的
etag
哈希值并不完全相同。嘗試使用上述
etag
值運作一個 cURL 請求:
1$ curl -I -H 'If-None-Match: "018b8b0ecb632aab770af328f043b119-ssl-df"' https://www.thepolyglotdeveloper.com/css/custom.min.css
2
3HTTP/2 200
4accept-ranges: bytes
5cache-control: public, max-age=0, must-revalidate
6content-length: 7328
7content-type: text/css; charset=UTF-8
8date: Wed, 04 Sep 2019 01:03:13 GMT
9strict-transport-security: max-age=31536000
10etag: "018b8b0ecb632aab770af328f043b119-ssl"
11age: 0
12server: Netlify
13x-nf-request-id: 2734ffab-c611-4fc9-841e-460f172aa3b4-1604468
複制
響應不是 304 代碼,因為
-df
表示它是 URL 的壓縮版本。就目前而言,我們的 cURL 請求針對的是 URL 的未壓縮版本。
Netlify 的支援工程師在這個論壇文章(https://community.netlify.com/t/excessive-bandwidth-usage/3036/17)中向我指出了這種差異。
在大多數情況下,Web 浏覽器将包含适當的标頭資訊以使用壓縮資源,是以在 cURL中,我們必須做一些不同的事。
為了使 cURL 超越此限制,以下請求将起作用:
1$ curl --compressed -I -H 'If-None-Match: "018b8b0ecb632aab770af328f043b119-ssl-df"' https://www.thepolyglotdeveloper.com/css/custom.min.css
2
3HTTP/2 304
4date: Wed, 04 Sep 2019 01:07:36 GMT
5etag: "018b8b0ecb632aab770af328f043b119-ssl-df"
6cache-control: public, max-age=0, must-revalidate
7server: Netlify
8vary: Accept-Encoding
9x-nf-request-id: 65a8e1aa-03a0-4b6c-9f46-51aba795ad83-1301670
複制
請注意,在上述請求中,我們在 cURL 中用了
--compressed
标志。結果收到了 304 響應,訓示資源沒有更改,我們應該使用本地緩存的副本。
或者,我們可以執行以下cURL請求:
1$ curl -I -H 'If-None-Match: "018b8b0ecb632aab770af328f043b119-ssl-df"' -H 'Accept-Encoding: gzip, deflate, br' https://www.thepolyglotdeveloper.com/css/custom.min.css
2
3HTTP/2 304
4date: Wed, 04 Sep 2019 01:12:34 GMT
5etag: "018b8b0ecb632aab770af328f043b119-ssl-df"
6cache-control: public, max-age=0, must-revalidate
7server: Netlify
8vary: Accept-Encoding
9x-nf-request-id: eca29310-c9bf-4742-87e1-3412e8852381-2432816
複制
而不是用
--compressed
标志,我們包含了
accept-encoding
标頭。
同樣,Netlify 的 Luke Lawson 在這個論壇文章(https://community.netlify.com/t/excessive-bandwidth-usage/3036/17)中提供了有關壓縮版本的資訊。
結論
您剛剛看到了如何用 cURL 模拟在 Web 浏覽器中的相同緩存。由于我是使用内容傳遞網絡(CDN)處理緩存的新手,是以對于測試緩存如何與任何給定資源的
etag
哈希一起工作對我來說非常有用。304 響應将始終比 200 響應更快地收到,并且有效負載更小,進而節省了帶寬和性能,同時又不犧牲内容的新鮮度。
從理論上講,CDN 會維護給定資源的版本資訊,是以将能夠驗證
etag
值的新鮮度。由浏覽器決定
etag
是否陳舊。
原文:https://www.thepolyglotdeveloper.com/2019/09/test-etag-browser-caching-curl-requests/