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
)。