我有一个SvelteKit网站,它有几个路由(比如/
和/about/
),运行在一个带有adapter-node
的Node.js服务器上。在本地先启动npm run build
,再启动node build
,一切正常,所有路由都可以访问:即加载localhost:4000/
打开主页,localhost:4000/about
打开关于页面。
然而,当我尝试将Node服务器置于具有条件路由的nginx反向代理之后时,除了顶级域之外的所有路由都停止工作,并进入重定向循环(301
-> 308
-> 301
-> ...
)。我做错了什么?
nginx服务器暴露于外部HTTP(S)流量,并设置为将所有与网站相关的请求路由到Node/SvelteKit服务器,***但***一些请求(/api/*
)需要转到另一个端口(3000
)上的另一个服务。因此,简单地将所有请求从nginx转发到带有location / { ... }
的SvelteKit是不可能的。以下是当前路由的设置方式:
user nginx;
worker_processes 1;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
# SvelteKit server on port 3000
upstream website {
server website_server:3000;
}
# Another server for /api/ on port 5000
upstream apis {
server api_server:5000;
}
server {
listen 80;
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
server_name mydomain.com www.mydomain.com;
# Route all /api/ requests to API server
location /api/ {
proxy_pass http://apis;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Route website requests to SvelteKit
location = / {
proxy_pass http://website;
# ... Same proxy_redirect and other contents as previous location block
}
location = /about/ {
# ... Same contents as previous location block
}
location /_app/ {
# ... Same contents as previous location block
}
location /images/ {
# ... Same contents as previous location block
}
location /css/ {
# ... Same contents as previous location block
}
location /fonts/ {
# ... Same contents as previous location block
}
}
}
1条答案
按热度按时间bvk5enib1#
在检查了请求和重定向之后,问题最终是关于尾随斜杠的。默认情况下,SvelteKit会删除所有尾随的斜杠,这意味着对
/about/
的请求将被重定向到/about
。然而,NGINX配置是使用/about/
路由设置的,因此它会将/about
请求重定向回/about/
,从而导致循环。要解决这个问题,可以做几件事:
1.可以编辑
nginx.conf
文件,使路由不包含尾随斜杠:+layout.server.js
文件中,添加export const trailingSlash = 'always';
行这两种方法稍有不同。方法1将使keep route请求成为绝对的,因此如果页面引用任何静态资产(即
/about
页面从/images/logo.jpg
加载图像),它们将正确解析为基本路径。方法2将使路由请求相对化,这意味着所有后续请求将从子路径开始,使/about/static/images/logo.jpg
成为新的资源路径。由于这不是期望的行为,因此方法1将更适合大多数用例。