【问题标题】:How can I check if file exists in nginx? otherwise run a rewrite rule如何检查文件是否存在于 nginx 中?否则运行重写规则
【发布时间】:2019-08-19 01:49:32
【问题描述】:

大家好,

为了动态调整图像大小,我决定使用 Kraken 或 imgix 之类的服务。

我的图片会这样显示:site.com/img/path-to-img-s250x250.jpg 我想要实现的是:如果图像path-to-img-s250x250.jpg存在,那么我会显示它,如果没有,则运行nginx重写规则来调整原始图像的大小并保存。

这是可能的还是我应该用 PHP 进行检查?

对于如何更好地处理动态调整图像大小,您还有什么更好的想法吗?

非常感谢

location /img/ {
    try_files $uri @getImg @resize;
}

location @getImg{
    rewrite "img/(.*)/([a-z0-9]+)-([0-9]+)x([0-9]+).([0-9]{5}).(jpg|jpeg|png|gif|ico)$" /img/$1/$2-$3x$4.$6 break;
}

location @resize{
    rewrite "img/(.*)/([a-z0-9]+)-([0-9]+)x([0-9]+).([0-9]{5}).(jpg|jpeg|png|gif|ico)$" $scheme://$host/image?path=$1&file=$2&ext=$6&w=$3&h=$4 break;
}

这是图片链接:site.com/img/prods/1002/filename-200x200.12345.jpg

12345 用于版本控制

【问题讨论】:

  • try_files 仅接受最后一个参数中的命名位置。您的 @getImg 术语被解释为文件名。您是否尝试测试两个替代文件名的存在?一个有版本号,一个没有版本号?
  • 其实所有图片都有版本号。不同之处在于该图像可以已经存储在硬盘中,在这种情况下,我只是将其显示为省略版本号(@getImg)。而第二种情况是如果图片不存在,需要通过Kraken.io生成并保存……希望你能更好的理解我
  • 我已经用你正在寻找的东西更新了答案。
  • 哦,太棒了,快到了 :) 我遇到了@resize 的问题:rewrite "^/img/(.*)/([a-z0-9]+)-([0-9]+)x([0-9]+).([0-9]{5}).(jpg|jpeg|png|gif|ico)$" $scheme://$host/image?path=$1&file=$2&ext=$6&w=$3&h=$4 break 重定向到带有所有查询字符串的 URL... :( 如果我不这样做使用$scheme://$host会返回404错误
  • 您想在内部重定向到 /image 处理程序,我认为它指向 PHP 脚本?根据您的脚本,您可能需要执行rewrite...last,或者您可能需要在@rewrite 块中包含所有相关的fastcgi 语句。

标签: nginx mod-rewrite url-rewriting


【解决方案1】:

您可以使用try_files 来测试一个或多个文件是否存在。详情请见this document

使用正则表达式 location 来捕获 URI 的元素。正则表达式位置按顺序计算,因此配置文件中的位置可能很重要。详情请见this document

如果try_files 语句的最后一个参数是一个URI。它将生成一个内部重定向。

例如:

location ~ "^/img/(.*)/([a-z0-9]+)-([0-9]+)x([0-9]+)\.([0-9]{5})\.(jpg|jpeg|png|gif|ico)$" {
    try_files $uri /img/$1/$2-$3x$4.$6 /image?path=$1&file=$2&ext=$6&w=$3&h=$4;
}

上述方法无法单独运行,因为许多 PHP 脚本使用最初请求的 URI (REQUEST_URI) 来确定路由。

您可以创建自定义位置来显式设置REQUEST_URISCRIPT_FILENAME 参数。

例如:

location = /image {
    include        fastcgi_param;
    fastcgi_pass   ...;
    fastcgi_param  SCRIPT_FILENAME  $document_root/index.php;
    fastcgi_param  REQUEST_URI      $uri$is_args$args;
}

将此块基于您现有的代码(以上只是猜测)。我们首先包含全局配置文件,然后覆盖SCRIPT_FILENAMEREQUEST_URI。我假设index.php 正在处理/image 路由。

【讨论】:

  • 感谢理查德的回复。我已经尝试过了,但它不起作用。我用我的代码更新了我的初始帖子。它实际上会跳过@getImg 并转到@resize,即使图像存在...但是如果我只使用try_files $uri @getImg; () 而没有@resize,图像会正确显示
  • 不知道怎么感谢你!奇迹般有效。万分感谢:)
  • 亲爱的@Richard,我已经更新了我最初的帖子以解决我遇到的一个小问题,请你看一下吗?谢谢
  • 你应该把它作为一个新问题发布。用已接受的答案重新打开一个旧问题只会让事情变得混乱。
  • 搞定了,这里是链接:stackoverflow.com/questions/55455163/…谢谢:)
猜你喜欢
  • 2011-11-27
  • 1970-01-01
  • 2014-07-19
  • 2011-12-19
  • 1970-01-01
  • 2021-06-02
  • 2019-09-02
  • 1970-01-01
  • 2014-05-09
相关资源
最近更新 更多