nginx在读取我的配置之前是否执行了重定向?

时间:2019-08-16 11:35:09

标签: nginx

我使用默认的nginx Docker容器配置进行了简单的nginx容器设置,并将一个React构建加载到其中。对于大多数用例来说,这很完美,但是我遇到了一个古怪的现象,在我得到的新应用程序中(我没有写过)它不起作用,我想了解如何解决此问题以及为什么nginx正以这种方式工作。

当客户请求地址https://example.com/abc/def.html时,他们会收到该页面,因为该页面存在。但是当他们请求https://example.com/abc/def时,它重定向到http://<internal-docker-container-IP>/abc/def/,但失败了,因为它在我的网络中无效。我知道IP和端口来自nginx配置,但是我不想为我部署的每个容器都重写它们,因为扩展性不好。

值得注意的是,nginx在此所做的所有操作都是在路径后添加斜杠,但同时也会重写主机和端口。我以为可以自己创建一个重写规则来添加尾部斜杠,但是似乎在执行过程中为时已晚。

在调试时,我尝试为著名的Web搜索引擎设置全局重写规则。我发现,在所有情况下,URL都没有重定向,除非URL没有斜杠。在那种情况下,我最终转到容器IP并获得连接超时。这对我来说似乎很奇怪。感觉好像有一个重写规则是在我的配置被点击之前触发的,但是我在配置中看不到它。

这是我的nginx.conf

worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/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  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

这是唯一包含的* .conf文件。这是容器的默认设置,除了我在第7行添加了重写:

    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    rewrite ^.*$ https://www.myforcedredirectfordebugpurposes.com redirect;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }


    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

我觉得重定向应该总是触发-毕竟,它在所有路径上-但是当我转到https://example.com/abc/def时,我最终遇到了失败的容器IP地址。如果我转到https://example.com/abc/def/(请注意末尾的斜杠),则重定向有效。这不是很奇怪吗?有没有一种方法可以配置它,而无需我在配置中对Nginx容器的地址进行硬编码?我以前从来没有这样做。

1 个答案:

答案 0 :(得分:0)

这可以通过在根try_files块中使用location指令来实现:

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri.html $uri/;
    }

在此额外的行中,传入的请求将首先尝试给定的URI,然后尝试添加了.html的URI,最后尝试了添加了/的URI。它将请求转发到第一个匹配项,而不显示给浏览器(因此浏览器不需要显示转​​发的地址)。

对于以前在末尾使用.html或以斜杠结尾的链接,是因为这些是Web服务器的有效uri:.html文件存在于这些路径中,并且由于行index index.html index.htm,尾部的斜杠表示隐式索引文件,因此nginx从目录内返回该文件。

我仍然不确定为什么我尝试的URL重写不起作用,但是获得所需的结果并不需要解决此问题,这是为了避免在其中指定服务器名称和端口配置。