Nginx
Nginx - 如何禁用error_page的重寫
我目前在 Fedora 25 Server Edition x86_64 上使用 Nginx 1.10.2 託管幾個小型靜態網站。
我已將 Nginx 配置為假設
.html
沒有文件副檔名 (try_files
) 的 for 請求,並在請求時將 (永久rewrite
) 重定向到.html
URL 的 -less 版本.*\.html
。我也有自定義錯誤頁面。據我目前所知,該
error_page
指令與重寫不能很好地配合,因為我遇到了應該返回正常錯誤消息的頁面的重定向循環……我相信這是所有相關的配置:server { [...] try_files $uri $uri.html $uri/index.html =404; error_page 400 /errors/400.html; error_page 401 /errors/401.html; error_page 403 /errors/403.html; error_page 404 /errors/404.html; error_page 408 /errors/408.html; error_page 500 /errors/500.html; error_page 503 /errors/503.html; # Remove "index" from URL if requesting the front page. rewrite "^/index(\.html)?$" "/" permanent; # Strip .html file extension, trailing slash, or "index.html". rewrite "/(.+)(\.html|/|/index.html)$" "/$1" permanent; [...] }
以下是我認為Nginx 正在做的事情:
- 客戶請求
/fake-page
- 查找
/fake-page
,/fake-page.html
或/fake-page/index.html
.- 當這些都不匹配時,內部重定向以顯示錯誤 404 頁面。
- 但隨後
/errors/404.html
被帶標誌的 .html 剝離permanent
,導致 301 使用者重定向。我在最後
rewrite
一行嘗試了幾種變體,甚至將它放在一個location ^~ /errors/ {}
塊中(我認為這應該意味著重寫只適用於不在/errors/ 目錄下的 URL)。但是我所做的一切都導致錯誤 404 永久重定向到 404頁面,然後它不會返回實際的 404 狀態 —或者它最終陷入重定向循環。
我建議您將
rewrites
內部location
塊包裹起來,否則很難控制它們的全球影響力。此範例似乎適用於您在問題中發布的程式碼段:
server { root /path/to/root; location / { # Remove "index" from URL if requesting the front page. rewrite "^/index(\.html)?$" "/" permanent; # Strip .html file extension, trailing slash, or "index.html". rewrite "/(.+)(\.html|/|/index.html)$" "/$1" permanent; try_files $uri $uri.html $uri/index.html =404; } error_page 400 /errors/400.html; error_page 401 /errors/401.html; error_page 403 /errors/403.html; error_page 404 /errors/404.html; error_page 408 /errors/408.html; error_page 500 /errors/500.html; error_page 503 /errors/503.html; location /errors/ { } }
這是一個棘手的問題,但最終可以按要求工作:
server { [...] root /path/to/root; set $docroot "/path/to/root"; error_page 400 /errors/400.html; error_page 401 /errors/401.html; error_page 403 /errors/403.html; error_page 404 /errors/404.html; error_page 408 /errors/408.html; error_page 500 /errors/500.html; error_page 503 /errors/503.html; location = /errors/404.html { root $docroot; internal; } location ~ ^/index(\.html)?$ { return 301 "/"; break; } location ~ ^/$ { try_files $uri $uri.html $uri/index.html =404; break; } location ~ ^/(.+)(\.html|/|/index.html)$ { if (-f $docroot/$1) { return 301 "/$1"; break; } if (-f $docroot/$1.html) { return 301 "/$1"; break; } if (-f $docroot/$1/index.html) { return 301 "/$1"; break; } try_files missing_file =404; } location ~ ^/(.+)(?!(\.html|/|/index.html))$ { try_files $uri $uri.html $uri/index.html =404; } [...] }
我稍後會嘗試用評論來擴展它;)