條件式請求(a conditional request)
想像你打電話到店裡問:「只有當你有比我三月買的更新的型號時才寄給我;否則別費事。」你就避免收到一個你早已擁有的笨重包裹。條件式請求就是網路版的那通電話。用戶端不是單純地說「把這個資源給我」,而是依據自己已持有的內容加上一個條件,讓伺服器只在用戶端的副本過期時,才回傳完整內容。
它是快取驗證背後的機制。兩個常見條件對應伺服器能發出的兩種驗證子。If-Modified-Since 帶著用戶端副本最後變更的日期,於是伺服器檢查「只有在此時間之後變過才送內文」。If-None-Match 帶著一個 ETag(版本指紋),於是伺服器檢查「只有在目前版本與此標籤不同才送內文」。若用戶端的副本仍是最新,伺服器回傳 304 Not Modified——一個只有標頭、沒有內文的小小回應——用戶端就重用手上已有的。若副本過時,伺服器回傳正常的 200 OK,連同完整的新內文與更新後的驗證子。
為什麼重要:條件式請求讓「過時」變得負擔得起。它讓快取在嚴格的新鮮度視窗之後仍保留內容,然後只花一次小小往返就確認它,而不必重新下載好幾 MB。它也支撐了許多 API 的高效輪詢與可續傳行為。誠實的限制:條件式請求仍要花一次往返——所以即使是 304,到伺服器的光速延遲也躲不掉。這正是為什麼能用就盡量用新鮮度(max-age):仍新鮮的副本完全不發請求就提供,而驗證是新鮮度過期後較便宜的退路。
一個天氣小工具每分鐘重新整理一個預報檔,做法是送出 If-Modified-Since: 帶著它上次看到該檔的時間。大多數分鐘什麼都沒變,所以伺服器回 304 Not Modified,小工具就保留目前資料——只花一次小小往返,而非完整重新下載。
下載前先問:304 代表你的副本仍然有效。
304 仍需抵達伺服器,所以當伺服器很遠或當機時它幫不上忙。條件式請求減少的是傳輸的位元組,不是往返次數——這正是為什麼在正確性允許時,新鮮內容(不發請求)勝過驗證。