我有一个 PHP 脚本,可以根据现有路径生成缩略图(更多信息)基本思想是这样的:
给定文档根目录/web/
,图像位于 中。当在 url 中请求/web/images/foo.jpg
名为 的预定义缩略图过滤器时,PHP 脚本会选择它,并在该位置生成缩略图,以便在下一个请求时直接通过 Nginx 提供该缩略图。thumb
/web/thumb/foo.jpg
现在,它可以使用以下(简化的)配置:
server {
location / {
try_files $uri @rewriteapp;
}
}
其中@rewriteapp
包含应用程序的重写规则。
问题是我想Expires
给缓存的缩略图添加一个标题。但是当我添加类似这样的内容时
location ~* \.(jpe?g|gif|png)$ {
expires 1y;
}
它只适用于生成的缩略图,但它会在应触发规则的请求上返回 404 @rewriteapp
。
我尝试在第一个 location 块之前或之后添加最后一个块,也尝试try_files
在 location w/expires 块内包含相同的语句。但这些都不起作用。
如何为图像添加标题?
更新:
下面接受的答案包含更详细的解释,说明为什么失败。就我而言,我通过将第二个位置块替换为以下内容来解决这个问题:
location /thumb/ {
try_files $uri @rewriteapp;
expires 1y; access_log off; log_not_found off;
}
答案1
我做的和你之前做的差不多,我将在下面复制我的 nginx vhost 代码
在这种情况下,位置块的排序基本上非常重要,如下所示:http://nginx.org/en/docs/http/ngx_http_core_module.html#location
无论如何,这是我的 nginx 代码 - 您可以根据本地环境对其进行修改:
location ~ ^/thumbnails/(.*)/(.*)$ {
try_files /thumbs/$1/cache/$2.jpeg /thumbs/$1/phpThumb.php?src=../../images/product/$2;
expires 6w;
fastcgi_hide_header Set-Cookie;
}
location ~* \.(ico|pdf|flv|jpg|jpeg|png|gif|js|swf|css|js)$ {
expires 6w;
}
需要注意的关键事项:缩略图目录不存在于磁盘上(它纯粹用于 try_files
这段代码基本上意味着对于传入的请求说/thumbnails/small/13909967441.JPG
它会尝试在/thumbs/small/cache/13909967441.JPG.jpg
(是的,我知道双扩展名 - 这是对性能的一种改进,我还能说什么呢!)中查找文件,如果找到,它会使用 expires 标头为它提供服务,如果找不到,它会在内部将请求重写为针对该大小配置的缩略图脚本,该脚本会生成图像并提供服务,在通过内部重写为 PHP 请求的请求中也会添加 expires 标头
这个诀窍具体来说是文档中的这一行:
如果最长匹配的前缀位置有“^~”修饰符,则不检查正则表达式。
这意味着,通过将重写/位置置于正则表达式规则之上(例如图像文件的通用规则),并确保标志和^~
或(在我的情况下~ ^
)(它们都等同于相同的规则)在其中可以防止正则表达式规则稍后匹配这是因为如果不是=
或^~
匹配,正则表达式规则通常会覆盖非正则表达式匹配
/thumbnails
由于上面提到的位置阻止了正则表达式匹配,并且正则表达式块位于位置块之后,因此无法在位置块之前匹配,因此命中路径的请求永远不会与图像文件的通用正则表达式匹配。
更新-根据您的 nginx 代码
您需要在位置 / 块中添加一个过期配置行,因为这将设置静态图像和来自重写块的图像的标题,显然您要么必须删除图像正则表达式位置块,要么将 ^~ 运算符添加到您的主要位置块