Nginx 中部署 React 项目刷新或输入url后404

部署完 React 项目后,通过ip访问服务器,页面正常打开。在没修改url的情况下刷新,报 404。在url中拼接路由也同样报 404。(linux服务器上,docker安装nginx)

将这个问题抛给 Claude (一款与GPT相同的AI),给出了下面的答案。

————————————————— AI answer ———————————————————
需要修改 Nginx 配置文件(nginx.conf),做以下几点:

  1. 配置静态文件路径,指向 React 项目构建后的 build 文件夹:
location / {
    root   /usr/share/nginx/html/react-proj/build;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
}
  1. 端口改为80,否则容器外部无法访问:
server {
    listen       80;  
}
  1. 允许前端 Javascript 的 CORS 请求:
add_header 'Access-Control-Allow-Origin' '*';
  1. 启动 Nginx 容器时,将 React 项目 build 后的文件映射到 Nginx 的指定路径,例如:
docker run -p 80:80 -v /my/host/path/react-proj/build:/usr/share/nginx/html/react-proj/build nginx

所以重点是修改静态文件路径和 CORS 设置,以及将 React 项目 build 后的文件映射到 Nginx 容器内的指定路径。
修改好 Nginx 配置文件后,使用 Dockerfile 构建 Nginx 镜像,然后运行容器就可以访问 React 项目了。

完整的 nginx.conf 文件如下:

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;

        location / {
            root   /usr/share/nginx/html/react-proj/build;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }
        
        add_header 'Access-Control-Allow-Origin' '*'; 
    }
}

主要修改了:

  • 监听 80 端口
  • location 指向 build 文件夹的静态文件
  • 设置 CORS 允许任意源

其他部分是 Nginx 的基本配置,保持默认即可。
你还可以添加其他 location 设置,例如代理 API 请求到后端服务等。
所以整个 Nginx 配置主要关注静态文件路径和 CORS 等基本设置,其他默认配置不必改动太多。

——————————————— AI answer end—————————————————

得到这份答案后,我查看了服务器中使用 docker 启动的 Nginx ,nginx.conf 文件映射到 /home/ubuntu/mysoft/docker-data/nginx/conf/ 文件夹下,在 /home/ubuntu/mysoft/docker-data/nginx/conf/conf.d 文件夹下有 default.conf 文件,Claude 提供的代码中 server 并没有写在 nginx.conf 文件中,而是在 default.conf 文件中。所以我没动 nginx.conf 文件,而是修改了 default.conf 文件。

如果各位的 server 在 nginx.conf 文件中,则可以按照 AI 给的答案尝试。

我使用 Xfip7 将 default.conf 文件下载,修改成下面代码的样子,在上传到原来位置。

补充了这两个

try_files $uri $uri/ /index.html;
add_header 'Access-Control-Allow-Origin' '*';
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

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

   
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    add_header 'Access-Control-Allow-Origin' '*';
}

修改后重启了 Nginx

docker restart [容器名称/ID]

再次尝试,就没有出现 404 了。


解释:
try_files $uri $uri/ /index.html; 这行配置的作用是:

  1. 首先尝试找到真实的文件来响应请求。比如请求 /about,则会尝试找 /about 这个文件。

  2. 如果找不到该文件,则尝试加上 / ,变成 /about/ 看是否有此文件夹。

  3. 上述均未找到文件或文件夹响应时,则返回 /index.html 文件。

其实这正是单页应用(SPA)需要的功能。单页应用一般只有一个 index.html 文件,它包含所有页面的代码

然后根据不同的 URL 显示不同的内容,但全部内容都嵌入在 index.html 中。

所以对于单页应用来说,大部分请求都找不到实际的文件,这个时候就需要返回 index.html 文件,让 JavaScript 代码根据 URL 渲染对应的页面。

try_files $uri $uri/ /index.html 这行配置正好做到了上述效果:

  1. 首先尝试找到真实请求的文件($uri)
  2. 再尝试加上 / ,找到的是文件夹则返回文件夹下 index.html 文件
  3. 都找不到则直接返回 /index.html 文件

因此对于单页应用,该配置非常重要。它可以让 Nginx 在找不到实际文件时,返回 index.html 文件,这样单页应用的路由就能正常工作了。


try_files 指令

try_files 是 Nginx 的一个非常有用的配置指令。

它的作用是:按顺序尝试匹配文件或者路径,直到找到一个存在的文件或者路径为止。

那么 try_files 语法是怎么样的呢?

基本形如:

try_files file1 file2 file3 ... /404.html;

举例:

try_files $uri $uri/ /index.html;
  • 检查 $uri(实际请求的 URI) 对应的文件是否存在,如果存在则返回此文件。
  • 如果$uri 对应的文件不存在,则尝试加上 / ,变成 $uri/ ,检查是否有此目录,如果有则返回此目录下的 index.html 文件。
  • 都没有找到,则返回 /index.html 文件。

也就是说,try_files 按顺序依次匹配:

  1. $uri 这个实际请求的 URI 对应的文件
  2. 加上 / 变成目录,$uri/ 目录下的 index.html 文件
  3. 全都没有找到,则返回 /index.html 文件

可以理解为一个 “按顺序尝试” 的意思,类似于:“尝试用 file1 响应,如果失败 then 尝试用 file2,如果还失败 then 尝试用 file3 …” ,直到找到一个存在的文件为止。

所以说,try_files 是一种非常简洁高效地根据 URI 检查与返回文件的方法。

—— C l a u d e A I Claude AI ClaudeAI

参考:
React部署于Nginx环境中刷新后404解决方案
react项目使用路由调整nginx 404

你可能感兴趣的:(nginx,react.js,运维)