带有 nginx 的 Gatsby - 重定向被破坏 - 尾随 /(斜杠)

Gatsby with nginx - redirect is broken - trailing / (slash)

我的 gatsby 站点重定向到尾部斜线,然后再次重定向回非尾部斜线。

nginx 配置文件:

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;

    server_name example.com;
    return 301 https://www.$server_name$request_uri;
}

server {
      listen 443 ssl http2;
        listen [::]:443 ssl http2;
        include snippets/ssl-example.com.conf;
        include snippets/ssl-params.conf;

        root /var/www/example.com/html;

        index index.html index.htm index.nginx-debian.html;

        server_name www.example.com;

        location ~ /.well-known {
                allow all;
        }

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        location ~* \.(?:html)$ {
          add_header Cache-Control "public, max-age=0, must-revalidate";
        }

        location = /sw.js {
          add_header Cache-Control "public, max-age=0, must-revalidate";
        }

        location /page-data {
          add_header Cache-Control "public, max-age=0, must-revalidate";
        }

        location /static {
          add_header Cache-Control "public, max-age=31536000, immutable";
        }

        location ~* \.(?:js|css)$ {
          add_header Cache-Control "public, max-age=31536000, immutable";
        }

    error_page  404  /404.html;
}

当我打开带有尾部斜线的网站时,我看到重定向到同一个 URL 但没有尾部斜线:

example.com/hello-world/ -> example.com/hello-world

这是预期的行为。

但是当我打开没有尾部斜线的网站时,我看到重定向到尾部斜线,然后再次重定向到没有尾部斜线。

example.com/hello-world -> example.com/hello-world/ -> example.com/hello-world

这不应该发生。我的配置哪里出错了?非常感谢任何帮助。

nginx

Nginx 关于斜杠的行为已记录 here

If a location is defined by a prefix string that ends with the slash character, and requests are processed by one of proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, or grpc_pass, then the special processing is performed. In response to a request with URI equal to this string, but without the trailing slash, a permanent redirect with the code 301 will be returned to the requested URI with the slash appended. If this is not desired, an exact match of the URI and location could be defined like this:

location /user/ {
    proxy_pass http://user.example.com; 
}

location = /user {
    proxy_pass http://login.example.com; 
}

这不适用于您,因为您没有使用 CGI 或上游应用服务器...您只是提供文件(如果我理解正确的话)。

我不是盖茨比专家,但从您评论中的link...

Gatsby works better, smoother, cleaner (etc.) with trailing slashes

有各种各样的 nginx 配置从已经成功使用 Gatsby 的人那里流传出来。例如one

与您最相关的部分是...

将不包含 .? 且不以 / 结尾的路径重定向到同一路径,但尾随 /.

例如将 /foo/bar 重定向到 /foo/bar/ 但不要混淆 /foo/bar.ext/fo.o/bar/foo/bar?hello.

rewrite ^([^.\?]*[^/])$ / permanent

尝试按以下优先顺序提供请求的 URI 解释:

  • 原样(文件路径)
  • 作为目录
  • 作为包含 index.html 个文件的目录
  • 如果上面的 none 是有效的,最后 404 错误
try_files $uri $uri/ $uri/index.html =404;

盖茨比

从你发布的 gatsby issue link 他们说了以下内容:

Explicitly use the trailing slash in all usages of the <Link> component and/or invocations of navigate()

Install gatsby-plugin-force-trailing-slashes. Even though Gatsby generates the static html pages within their own named directories by default, this plugin forces the path value for each page to end in a / - critical for configuring the core Gatsby @reach/router at build time.

然后最终重建 gatsby 站点,因为其中一些配置仅在构建时有影响。