對於給定的 URL 模式 ( /scripts/.*\.meta\.js
),我希望有以下行為:
- 如果URL中包含特定參數(
version
),則將請求交給Passenger處理。 - 如果 URL 不包含該特定參數且存在快取文件,則提供該文件。
- 如果 URL 不包含該特定參數且快取檔案不存在,則將請求交給 Passenger 處理。
我這樣做是為了避免 Passenger 及其背後的 Rails 應用程式必須處理對該路徑的大多數請求,從而提高效能。
我的 nginxconf 檔案是:
server {
listen 80;
server_name my.site;
root /path/to/rails/public;
passenger_enabled on;
rails_env development;
passenger_min_instances 1;
client_max_body_size 5m;
location ~* /scripts/.*\.meta\.js {
error_page 418 = @noparams;
if ( $arg_version = '' ) {
return 418;
}
}
location @passenger {
root /path/to/rails/public;
proxy_set_header X-Forwarded-Proto http;
passenger_enabled on;
}
location @noparams {
try_files /a$uri @passenger =401;
}
}
我已將測試文件放在/path/to/rails/public/a
.這給了以下行為:
- ✓ 如果 URL 包含特定參數(
version
),則將請求交給 Passenger 處理。 - ✓ 如果 URL 不包含該特定參數且存在快取文件,則提供該文件。
- ❌ 如果 URL 不包含該特定參數且快取檔案不存在,則將請求交給 Passenger 處理。實際行為:HTTP 401。
看來我所擁有的並不是 中引用 Passenger 的正確方法try_files
。我需要做什麼才能讓這項工作成功?
答案1
我的印像是,這try_files
是一個要嘗試的“事物”列表,您可以在任何位置放置一個命名位置。正如邁克爾漢普頓在評論中指出的那樣,這是不正確的。命名位置和 HTTP 代碼只能位於try_files
;中的最後位置。不在最後位置的任何內容都必須是檔案路徑。所以try_files /a$uri @passenger
按我的意圖工作。
也無需重複內部配置,@passenger
因為它是從server
區塊繼承的。所以一個工作配置是:
server {
listen 80;
server_name my.site;
root /path/to/rails/public;
passenger_enabled on;
rails_env development;
passenger_min_instances 1;
client_max_body_size 5m;
location ~* /scripts/.*\.meta\.js {
error_page 418 = @noparams;
if ( $arg_version = '' ) {
return 418;
}
}
location @passenger { }
location @noparams {
try_files /a$uri @passenger;
}
}