首页 > 解决方案 > Nginx try_files 不适用于附加斜杠的域

问题描述

我有一个 dockerised Django 应用程序,其中 nginx 使用 proxy_pass 将请求发送到 Django 后端。我希望预先发布某些不经常更改的页面,以便 Django 不必处理它们。

我正在尝试使用 try_files 检查该页面是否在本地存在,如果不存在则传递给 Django。

我们的 URL 结构要求所有 URL 都以正斜杠结尾,并且我们不使用文件类型后缀,例如页面可能是 www.example.com/hello/。这意味着在这个实例中 nginx 中的 $uri 参数是 /hello/ 并且当 try_files 查看它时,由于尾部斜杠,它期待一个目录。如果我有一个包含文件列表的目录,如何让 try_files 查看它们而不重写 URL 以删除 Django 需要的斜杠?

我的 nginx 配置如下。

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name example.com;

    root /home/testuser/example;

    location / {
        try_files $uri uri/ @site_root;
    }

    location @site_root {
       proxy_pass         http://127.0.0.1:12345;
    }
}

如果我在 /home/testuser/example/hello 有一个文件“hello”并调用https://www.example.com/hello/我怎样才能让它正确加载文件?

PS静态内容文件夹及其内容的权限都是777(暂时排除权限问题)

提前干杯!

标签: djangonginxurl-rewriting

解决方案


您可以将 URI 指向/hello/名为hellohello.htmlusing的本地文件try_files,但您必须首先使用正则表达式提取文件名location。有关详细信息,请参阅此文档

使用的好处.html是您不需要提供响应的 Content-Type。

例如,使用hello.html

root /path/to/root;

location / {
    try_files $uri uri/ @site_root;
}
location ~ ^(?<filename>/.+)/$ {
    try_files $filename.html @site_root;
}
location @site_root {
   proxy_pass  ...;
}

如果您喜欢存储没有扩展名的本地文件,并且它们都是text/html,则需要提供 Content-Type。有关详细信息,请参阅此文档

例如,使用hello

root /path/to/root;

location / {
    try_files $uri uri/ @site_root;
}
location ~ ^(?<filename>/.+)/$ {
    default_type text/html;
    try_files $filename @site_root;
}
location @site_root {
   proxy_pass  ...;
}

推荐阅读