【问题标题】:Redirect Image file not found to Uri with NGinx使用 NGinx 将找不到的图像文件重定向到 Uri
【发布时间】:2018-11-25 04:20:21
【问题描述】:

我正在将 Laravel 网站从 Apache (htaccess) 切换到 NGinx。我已经构建了一个图像服务,它生成一个带有适当参数的 uri,用于调整 ex 大小:pics/images/max24h/music_video_red_icon.png。 我 Apache 没有找到将其重定向到路由 image/images/max24h/music_video_red_icon.png 的文件,laravel 中的操作在该路由中创建并返回图像。在.htaccess 中,它适用于以下代码:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^pics(.*)\.(jpe?g|png|gif|ico|bmp)$ /image$1.$2 [R=307,L]

现在在 NGinx conf 中,如何正确重定向它?我尝试了很多建议,例如:

# Redirect pics file not found to php laravel route to create the image
location @img_proxy {
    rewrite ^/pics(.*)\.(jpe?g|png|gif|ico|bmp)$ /image$1.$2;
}

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

它根本不起作用,如果我删除这些行,服务器就会起作用。我正在使用 Mac High Sierra 10.13.6 。会不会是一些配置冲突?这是完整的nginx.conf

user _www _www;

worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen 80 default_server;
        server_name localhost;
        root /var/www/megalobiz/public;

        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Content-Type-Options "nosniff";

        index index.html index.htm index.php;

        charset utf-8;

        gzip on;
            gzip_vary on;
            gzip_disable "msie6";
            gzip_comp_level 6;
            gzip_min_length 1100;
            gzip_buffers 16 8k;
            gzip_proxied any;
            gzip_types
                text/plain
                text/css
                text/js
                text/xml
                text/javascript
                application/javascript
                application/x-javascript
                application/json
                application/xml
                application/xml+rss;

        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }

        error_page 404 /index.php;

        # removes trailing slashes (prevents SEO duplicate content issues)
        #if (!-d $request_filename)
        #{
        #    rewrite ^/(.+)/$ /$1 permanent;
        #}

        # Redirect pics file not found to php laravel route to create the image
        location ~ ^/pics(.*)\.(jpe?g|png|gif|ico|bmp)$ {
            try_files $uri @img_proxy;
        }

        location @img_proxy {
            rewrite ^/pics(.*)\.(jpe?g|png|gif|ico|bmp)$ /image$1.$2;
        }

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location ~ \.php$ {
            try_files      $uri =404;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

        location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|svg|woff|woff2|ttf)\$ {
            expires 1M;
            access_log off;
            add_header Cache-Control "public";
        }
        location ~* \.(?:css|js)\$ {
            expires 7d;
            access_log off;
            add_header Cache-Control "public";
        }

        location ~ /\.(?!well-known).* {
            deny all;
        }

        location ~ /\.ht {
            deny  all;
        }
    }

    include servers/*;
}

【问题讨论】:

  • 您缺少;。使用nginx -t 测试您的配置。
  • 对不起。我可能因为玩它而想念它。现在服务器正在工作,但收到带有http://localhost/pics/images/max24h/music_video_red_icon.png 的 404 响应页面,就像我使用的其他变体一样。我开始怀疑配置冲突或优先级,我对 NGinx 了解不够。
  • 你的 location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|svg|woff|woff2|ttf)\$ 块将阻止 Laravel 看到重写的 /images/ URI。
  • 似乎合乎逻辑。但是我删除了两个缓存规则,仍然是 404 页面。
  • 您的 apache 代码正在执行外部重定向(307 响应) - 为了让 Nginx 执行外部重定向,您需要将 redirect 附加到您的 rewrite 语句(用于 302 响应)。如果您需要使用 307,则需要稍微复杂一些的东西。

标签: macos nginx


【解决方案1】:

.htaccess 文件的功能与您的rewrite 语句的主要区别在于,Apache 将使用 307 响应执行外部重定向,而 Nginx 执行内部重定向。详情请见this document

要强制 Nginx 执行外部重定向,请将 permanentredirect 标志附加到 rewrite 语句,这将分别生成 301 或 302 响应。

例如:

location @img_proxy {
    rewrite ^/pics(.*)\.(jpe?g|png|gif|ico|bmp)$ /image$1.$2 redirect;
}

302 和 307 响应之间的区别在于,后者将重定向 POST 请求方法而不将其更改为 GET。

如果您需要重定向 POST 请求,则需要使用 正则表达式 locationif 块捕获 URI 的相关部分,并改用 return 307

例如:

location @img_proxy {
    if ($uri ~ ^/pics(.*)\.(jpe?g|png|gif|ico|bmp)$) {
        return 307 /image$1.$2$is_args$args;
    }
}

请参阅this caution 了解if 的使用。

【讨论】:

  • 很好的解释。感谢您带我走上正确的道路。
猜你喜欢
  • 2020-08-29
  • 2020-07-17
  • 2017-04-07
  • 2012-07-08
  • 2011-06-14
  • 2014-03-08
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
相关资源
最近更新 更多