nginx:如何在反向代理中直接處理某些檔名(*.txt)的404?

nginx:如何在反向代理中直接處理某些檔名(*.txt)的404?

我有一個複雜的nginx設置,其中連接埠 80 和 443 的前端nginx處理包括 TLS 在內的所有外部存取。

對於 frontend-nginx 中的文件,/texts請求應代理到第二個 backend-nginx,後者會在複雜的過程中動態修改現有文字文件,從而佔用 CPU 和其他資源。

對於那些不存在的檔案*.txt(404),我希望根本不打擾後端,而是直接向客戶端提供預設檔/texts/default.txt。然而,目前不存在的檔案仍然只能在後端的error_page 404線路中處理。現有文件的服務沒有問題,代理可以工作。

這是我的配置:

frontend-nginx.conf:
http {
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  frontend.example.org;
        root         /srv/www;

        location /texts/ {

            location ~ \*.txt$ {
                root /srv/www/backend;

                ####### the next line has absolutely no effect
                try_files $uri /texts/default.txt;
            }

            proxy_pass          http://localhost:90;
            proxy_redirect      http://localhost:90/ /;
            proxy_set_header    Host             $host;
            proxy_set_header    X-Real-IP        $remote_addr;
            proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header    X-Client-Verify  SUCCESS;
            proxy_set_header    Upgrade          $http_upgrade;
            proxy_set_header    Connection       "upgrade";
            proxy_http_version  1.1;

            proxy_redirect off;
        }
    }
    # https goes here, all the same except TLS
}
backend-nginx.conf:
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;

    server {
        listen       127.0.0.1:90;

        root /srv/www/backend;
        charset utf-8;

        expires -1;  # no-cache
        location ~ /..*\.txt$ {
            # longer cache time for text files
            expires 10m;

            # this actually works but only here in the backend
            error_page  404 @404;
        }

        location @404 {
            return 302 $scheme://frontend.example.org/texts/default.txt
        }
    }
}

我在前端設定檔中有一個無用的語句,在我看來它好像可以處理 404 重定向,default.txt但是當我這樣做時

wget -v http://frontend.example.org/texts/notexist.txt

我僅在後端內部獲得重定向(因此確實發生了代理)。

答案1

location /texts/ {
    proxy_set_header ...;
    proxy_pass ...;

    location ~ \.txt$ {
        root /path/to/root;
        try_files $uri /texts/default.txt;
        proxy_pass ...;
    }
}
location = /texts/default.txt {
    root /path/to/root;
}

請注意該語句的正確正規表示式location。這些proxy_set_header語句將被繼承,但該proxy_pass語句需要在嵌套的location.

try_files語句將檢查檔案是否存在,如果不存在則更改 URI。

預設檔案有一個專用的location,以便該檔案可以作為來自正確根目錄的靜態檔案。

檔案的路徑是透過將 的值root與 URI 連接起來建構的,因此檔案/texts/default.txt位於/path/to/root/texts/default.txt

相關內容