You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+React部署Ubuntu Nginx后静态资源404问题求助

路径加载404问题排查与解决思路

环境与代码

技术栈

  • Node.js(Express)后端 + React前端
  • 部署环境:DigitalOcean Ubuntu 22.04 + Nginx

Express服务器代码(main.js)

// main.js
const Port_TCP = 3005;

const express = require('express'); 
const path = require("path");

let app = express();
app.use(express.json());
app.use(express.static(__dirname + '/public'));
app.set('port', Port_TCP);

app.get("*", function(req, res) {
    res.sendFile(path.join(__dirname, '/public/index.html'))
})

app.listen(Port_TCP);

前端入口文件(public/index.html)

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>My website</title>
    <link href="css/app.css" rel="stylesheet">
    <link rel="icon" type="image/x-icon" href="imgs/ico.png">
</head>
<body>
    <!-- React root DOM -->
    <div id="MainRouter"></div>
    <!-- React JS -->
    <script type="application/javascript" src="js/app.js" defer></script>
</body>
</html>

问题表现

  • 本地Windows环境运行完全正常
  • 部署到Ubuntu服务器后,index.html能加载,但所有静态资源报404:

GET https://my-website.com/css/app.css net::ERR_ABORTED 404 (Not Found)
GET https://my-website.com/js/app.js net::ERR_ABORTED 404 (Not Found)
标签图标同样无法找到

补充信息

  • 服务器上删除app.get("*")代码块后仍能访问页面,但本地这么做会出现502错误
  • 项目文件夹结构:
/main.js (server)
/mix-manifest.json
/package.json
/package-lock.json
watcher.js (for nodemon)
webpack.mix.js
/js and /sass folder (which contain react project)
/public/
/public/index.html
/public/css/app.css
/public/js/app.js
/public/imgs/
  • Nginx配置(/etc/sites-available):
server {

        root /var/www/mywebsite.fr/public;
        index index.html index.htm index.nginx-debian.html;

        server_name mywebsite.fr www.mywebsite.fr;

        location / {
               proxy_pass http://localhost:3005;
               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;
               try_files $uri $uri/ =404;
        }

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mywebsite.fr/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mywebsite.fr/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}
server {
    if ($host = www.mywebsite.fr) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = mywebsite.fr) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name mywebsite.fr www.mywebsite.fr;
    return 404; # managed by Certbot
}

解决思路

1. 修复Nginx配置冲突

当前Nginx同时设置了root指向静态目录和proxy_pass转发请求,导致静态资源请求被双重处理,出现冲突。两种可选方案:

  • 方案一:完全由Express托管静态资源
    删除Nginx中的root和index配置,同时移除location /里的try_files $uri $uri/ =404;,让所有请求都转发给Express处理:
    location / {
           proxy_pass http://localhost:3005;
           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;
    }
    
  • 方案二:Nginx直接处理静态资源
    新增location匹配静态资源后缀,让Nginx直接返回文件,剩余请求转发给Express:
    location ~* \.(css|js|png|ico)$ {
            root /var/www/mywebsite.fr/public;
            expires 30d;
    }
    
    location / {
           proxy_pass http://localhost:3005;
           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;
    }
    

2. 优化Express静态资源路径写法

Windows与Linux路径分隔符存在差异,建议使用path.join统一处理路径,避免潜在兼容问题:

// 替换原express.static行
app.use(express.static(path.join(__dirname, 'public')));

同时检查服务器public目录权限,确保Node进程有读取权限:

sudo chmod -R 755 /var/www/mywebsite.fr/public
sudo chown -R www-data:www-data /var/www/mywebsite.fr/public

3. 验证静态资源实际存在性

登录服务器确认/var/www/mywebsite.fr/public/css/app.css、/var/www/mywebsite.fr/public/js/app.js等文件是否存在且内容正确,排查部署时是否遗漏打包文件或webpack打包路径错误。

4. 调整路由 fallback优先级

Express中express.static的优先级高于路由,正常情况下静态资源会被优先返回,但Nginx的try_files会导致本地找不到文件时直接返回404,跳过转发给Express的步骤,因此必须移除该行配置。

内容的提问来源于stack exchange,提问作者koesys

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:15:24