在 ubuntu 服务器中,我有两个版本的 node.js + express 和 reactjs 应用程序,一个用于测试,另一个用于生产。它们的路径类似于(抱歉,描述得不好。如果您有任何改进建议,请告诉我):
/home/usr/app_name/[test or prod]/client/index.html;
/home/usr/app_name/[test or prod]/client/assets/(index.js & index.css);
/home/usr/app_name/[test or prod]/server/(config & dist & node_modules & package.json & package-lock.json);
首先,我的节点应用程序使用 express 提供静态文件,但由于我为其实施了 HTTPS,因此我决定使用 nginx 作为反向代理和 Web 服务器。我的想法是让 nginx 监听端口,提供我的静态文件并将请求转发到我的节点 API。当用户到达“uri”时,它必须提供生产文件,而“uri/test”必须提供测试文件,因此我在 sites-available 上定义了以下内容并链接到 sites-enabled:
server {
listen 3000 ssl;
listen [::]:3000;
server_name my_domain www.my_domain;
ssl_certificate /path/to/ssl_certificate.crt;
ssl_certificate_key /path/to/private/ssl_private_key.key;
location / {
alias /home/usr/app_name/prod/client/dist;
index index.html;
try_files $uri $uri/ @backend_prod;
}
location @backend_prod {
proxy_pass http://127.0.0.1:5001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /test {
alias /home/usr/app_name/test/client/dist;
index index.html;
try_files $uri $uri/ @backend_test;
}
location @backend_test {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
在我使用之前root
代替alias
,但 nginx 正在通过/test
作为我的路径的一部分,所以我收到有关它的请求的错误/test/assets/index
。使用上面提供的配置,我得到了:
2024/04/18 15:52:05 [错误] 34477#34477:*1 open()“/usr/share/nginx/html/assets/index-f38f2b09.js”失败(2:没有此文件或目录),客户端:IP,服务器:my_domain,请求:“GET /assets/index-f38f2b09.js HTTP/1.1”,主机:“my_domain:5000”,引荐来源:“https://my_domain:5000/test/”
在浏览器上它给了我一个无法加载资源:服务器响应状态为 502(错误网关)。
我找到了两种解决方法。添加:
location /assets {
alias /home/usr/app_name/test/client/dist/assets;
}
或者try_files $uri $uri/ @backend_test;
改为try_files $uri $uri/ index.html;
并location @backend_test {
改为location /api {
。
现在我又陷入了另一个问题。这是我的客户执行的请求的示例:
await fetch("/api/users/me", {
method: "GET",
credentials: "include",
});
这就是我的服务器端处理它的方式:
应用程序.ts:
private router(): void {
this.app.use("/", routes);
this.app.use(handleAllErrors);
}
路线.ts:
router.get(
"/api/users/me",
authenticate,
userController.getMe.bind(userController)
);
我删除了authenticate
并执行了 get 使用curl
并且它返回了预期的结果,但是当我使用 nginx 时,我被卡住了:
2024/04/18 15:57:10 [错误] 35226#35226:*1 open()“/usr/share/nginx/html/api/users/me”失败(2:没有此文件或目录),客户端:IP,服务器:my_domain,请求:“GET /api/users/me HTTP/1.1”,主机:“my_domain:5000”,引荐来源:“https://my_domain:5000/test/”
我试过:
将服务器端位置更改为
location /api {
或location /test/api {
,但我仍然收到相同的错误;我也尝试测试
location / {
,它返回的是 nginx html 而不是我的文件;我已经使用 chmod +x 为我的静态文件路径提供必要的权限;
我尝试将
location /api {
,location /test/api {
和location @backend_test {
放在location /test {
; 里面,更改proxy_pass http://127.0.0.1:5000;
为proxy_pass http://127.0.0.1:5000/;
,但它说:
nginx:[emerg] 位置“/api”位于 /etc/nginx/sites-enabled/my_domain:30 中位置“/test”之外 nginx:配置文件 /etc/nginx/nginx.conf 测试失败
- 我尝试更改为
location @backend_test {
或location @backend_test/ {
,但它显示:proxy_pass http://127.0.0.1:5000;
proxy_pass http://127.0.0.1:5000/;
nginx:[emerg]“proxy_pass”不能在正则表达式给出的位置、命名位置内、“if”语句内或 /etc/nginx/sites-enabled/my_domain 中的“limit_except”块内有 URI 部分
- 经过一些测试,我重新启用了我的 nodejs 服务器来提供我的静态文件,并尝试仅使用 nginx 作为反向代理,但是我发现了另一个问题:当我通过删除和注释来配置为 http 时,它可以正确代理
ssl
,listen 3000 ssl;
但是ssl_certificate/path/to/ssl_certificate.crt; ssl_certificate_key/path/to/private/ssl_private_key.key;
当我配置 https 时,它只显示带有“欢迎使用 nginx...”的 nginx index.html;
提前感谢您并对任何语法错误表示歉意!!