Nginx重写URL仅在文件存在的情况下


13

我需要为Nginx编写一个重写规则,以便如果用户尝试转到旧的图像URL:

/images/path/to/image.png

并且文件不存在,请尝试重定向到:

/website_images/path/to/image.png

仅当图像存在于新的URL中时,否则继续404。我们主机上的Nginx版本尚没有try_files。

Answers:


19
location /images/ {
    if (-f $request_filename) {
        break;
    }

    rewrite ^/images/(.*) /new_images/$1 permanent;
}

但是,您可能想调试主机以进行升级或找到更好的主机。


这会在每个404上重定向到/ new_images吗?我不想重写,除非我知道new_images文件存在
Jose Fernandez 2010年

这将检查文件是否存在,如果该测试失败,它将重定向到new_images。此后未指定发生的情况。
tylerl


2
@riverfall嘿,我写了那页的一部分。我的答案写于8年前,是的,这有点过时了,但是最初的问题明确指出他们的主机没有提供nginx的最新版本,因此他们无法访问try_files。
Martin Fjordvald

1
@ Guillaume86我不会担心,if +重写是完全安全的,并且对文件的单个STAT检查非常轻巧。这比去后端应用程序检查维护模式要快得多。
马丁·峡湾

6

请不要if在位置限制内使用。坏事可能发生。

location ~* ^/images/(.+)$ {
    root /www;
    try_files /path/to/$1 /website_images/path_to/$1 /any/dir/$1 @your404;
}

$1 成为可以在try_files指令中尝试的文件名,该指令是针对您要完成的工作而创建的。

否则,只需重写它即可,无需检查。如果该图像不存在,无论如何您将得到404。


尽管此答案严格地不能回答问题(“ [no] try_filesyet”),但对于将来来这里的访客而言,此答案值得更多投票。
DerMike

5

您可以使用类似以下内容(针对您的特定情况而未经测试):

location ^/images/(?<imgpath>.*)$ {

    set $no_old  0;
    set $yes_new 0;

    if (!-f $request_filename)
    {
        set $no_old 1;
    }

    if (-f ~* "^/new_path/$imgpath")
    {
        set $yes_new 1$no_old;
    }

    # replacement exists in the new path
    if ($yes_new = 11)
    {
        rewrite ^/images/(.*)$ /new_path/$1 permanent;
    }

    # no image in the new path!
    if ($yes_new = 01)
    {
        return 404;
    }
}

基本上,这是编写嵌套if语句的另一种方法,因为您不能在Nginx中嵌套。有关此“ hack”的官方参考,请参见此处

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.