尝试使用 Nginx try_files 模拟 Apache MultiViews

尝试使用 Nginx try_files 模拟 Apache MultiViews

http://example.com/foobar我想要一个返回的请求http://example.com/foobar.jpg。(或者 .gif、.html 或 .whatever)

对于 Apache MultiViews 来说这很简单,而且在 Nginx 中似乎也同样容易。这个问题似乎暗示它会像try_files $uri $uri/ index.php;在位置块中一样简单,但这并不起作用。

try_files $uri $uri/ =404;不起作用,也不起作用,try_files $uri =404;或者try_files $uri.* =404;将它在我的location / {块和匹配图像的正则表达式之间移动没有效果。

至关重要的是,try_files $uri.jpg =404; 有效,但仅适用于 .jpg 文件,并且如果我在位置块中使用多个 try_files 规则,它会引发配置错误!

当前server {区块:

server {
        listen   80;
        server_name     example.org www.example.org;
        access_log  /var/log/nginx/vhosts.access.log;
        root   /srv/www/vhosts/example;
        location / {
                root   /srv/www/vhosts/example;
        }

        location ~* \.(?:ico|css|js|gif|jpe?g|es|png)$ {
                expires max;
                add_header Cache-Control public;
                try_files $uri =404;
        }
}

Nginx版本是1.1.14。

答案1

您可以通过传递各种文件名来尝试模拟 Apache 的 MultiViews try_files

Nginx 的try_files指令的作用正如其名称所示 - 它会按照指定的顺序尝试文件,如果找不到,则会移动到下一个文件。通常,最后一个条目是保证有效的后备 - 要么是命名的位置块,要么是错误页面。

常见的参数有try_files$uri并且$uri/确实是传递给 nginx 的路径 - 带有和不带有尾随斜杠。

所以,如果你去example.com/path/to/myfile

$uri = /path/to/myfile
$uri/ = /path/to/myfile/

使用该try_files $uri $uri/指令,nginx 将准确尝试传递的内容($uri) - 如果该文件存在,则将提供该文件,否则将尝试查找匹配的目录($uri/)并提供该文件(使用您指定的任何索引)。

由于您尝试提供的文件实际上与 中的路径不匹配$uri,因此您需要将扩展​​名附加到$uri才能使其正常工作:

$uri.jpg将匹配(从上面的例子)myfile.jpg- 因此为什么当你使用它时只有 JPEG 有效。

由于您可以指定多个文件进行尝试try_files,因此拥有多个try_files指令实际上没有意义 - 这就是不允许的原因。

因此,以最简单的形式,只需按照您希望尝试的顺序列出您想要的文件(例如):

try_files $uri.jpg $uri.gif $uri.png $uri.css $uri.js $uri/ =404

在这种情况下,第二个位置块很有趣。通常,nginx 只会处理一个位置块 - 最匹配的位置块。但是,在rewrite ... last处理的情况下,将重新启动并检查所有可用的位置块。这本质上相当于try_files- 检查是否存在和rewrite ... last,关键区别在于传递的参数不存在,try_files除非明确添加(例如使用$uri?$args)。

相关内容