我們注意到,當使用 nginx 內部 301 和 302 處理時,nginx 將提供一個帶有適當 Location: ... 標頭的小文檔主體。
類似的內容(在 html 中):301 重定向 - nginx。
根據上述行為,也會傳送內容類型 text/html 和內容長度標頭。
我們做了很多 302 和一些 301 重定向,我們認為上述行為浪費了頻寬。
有什麼方法可以停用這種行為嗎?
我們想到的一個想法是將 error_page 301 302 設定為空文本檔。我們尚未對此進行測試,但我假設即使使用上述內容,也會發送內容類型和內容長度 (0) 標頭。
那麼,有沒有一種乾淨的方法來使用 nginx 發送“無正文”301/302 重定向?
答案1
仔細考慮你的要求,並認真考慮不做。
RFC 2616指定要刪除的實體主體應該存在。
10.3.2 301永久移動
新的永久 URI 應由回應中的位置欄位給出。除非請求方法是 HEAD,否則回應實體應該包含一個簡短的超文本註釋,其中包含指向新 URI 的超連結。
和...
10.3.3 找到 302
臨時 URI 應由回應中的位置欄位給出。除非請求方法是 HEAD,否則回應實體應該包含一個簡短的超文本註釋,其中包含指向新 URI 的超連結。
在這種情況下,應該定義在RFC 2119:
這個詞或形容詞「推薦」意味著在特定情況下可能存在忽略特定項目的正當理由,但在選擇不同的路線之前必須理解並仔細權衡其全部含義。
現在您可以在不違反 RFC 的情況下執行此操作,但您應該了解完整的含義:
- 你做了很多工作卻幾乎沒有好處。我能想到的禁用實體主體的唯一合乎邏輯的原因是節省頻寬成本,實際上這就是您提到的原因,但差異非常小,以至於您甚至不太可能在頻寬圖表上看到差異。
- 極少數 Web 用戶端不會自動遵循 3xx 重定向。在編寫 RFC 時,這一比例要大得多,這就是為什麼它首先存在的原因,但仍然有古老的怪物潛伏在黑暗的臥室和資料中心壁櫥的陰影中,有時它們會出來玩耍。您最有可能看到的是
curl
,它仍然很常用。
這項建議已有所放寬RFC 7231,它僅僅表示(對於 301 和 302):
伺服器的回應負載通常包含一個簡短的超文本註釋,其中包含指向新 URI 的超連結。
伺服器的回應負載通常包含一個簡短的超文本註釋,其中包含指向不同 URI 的超連結。
答案2
是的你可以絕對地使用 NGINX 來做吧!
只需安裝一個異常處理程序,又名
error_page
,對所需的回應進行後處理。確保以防止錯誤頁面修改 HTTP 狀態代碼的方式進行設置,例如,不要使用該=
參數(或使用它來硬編碼您想要的任何代碼)。確保
return
帶有返回狀態代碼的回應,允許您選擇設置[text]
,而不是URL
.指定
default_type
of""
,這似乎刪除了Content-Type
標題
這是完整的程式碼,也在我的GitHub在StackOverflow.cnst.nginx.conf
儲存庫:
# cat sf.421976.301-302-redirect-w-no-http-body-text.nginx.conf | sed 's#^#\t#g'
server {
listen 1976;
error_page 301 302 @30x; # keep original HTTP status code w/o `=`
location @30x {
default_type ""; # will remove Content-Type completely
# `300` is a filler: client will get the original HTTP status code
return 300;
}
return 301 http://example.su/test;
}
這是其正常工作的確認:
% curl -i localhost:1976 | sed 's#^#\t#g'
HTTP/1.1 301 Moved Permanently
Server: nginx/1.2.1
Date: Mon, 28 Aug 2017 22:02:41 GMT
Content-Length: 0
Connection: keep-alive
Location: http://example.su/test
%
我已經在瀏覽器中嘗試過了,它也運行得很好。
PS 另一個選擇是修改原始碼,並編輯ngx_http_error_301_page
等變量,但為什麼要走艱難的道路? ^_^
答案3
這有點難看,但也許您可以代理 301/302 請求並使用 proxy_method 將 GET 更改為 HEAD 請求。我還沒有測試過它,但頭請求應該只發送沒有回應的標頭或(希望)content-* 標頭。