React项目Nginx子目录部署时static静态资源无法访问如何解决
你在package.json中配置homepage值为/example后,React打包生成的index.html内所有静态资源引用都会自动拼接/example前缀,最终请求路径类似/example/static/js/main.xxx.js。但你当前的Nginx配置仅处理根路径/的请求,没有针对/example前缀的路由规则,请求到达Nginx后会默认去/usr/share/nginx/html/example/目录下查找文件,而你直接把build产物放在了html根目录,不存在example这个子文件夹,自然所有静态资源都会返回404。
两种方案二选一即可,优先选第一种,无需重新打包:
方案1:调整Nginx路由+文件目录(推荐)
- 先在Nginx的静态资源目录下新建example文件夹:
mkdir -p /usr/share/nginx/html/example - 把React build目录下的所有文件(index.html、static文件夹、asset-manifest.json等)全部移动到刚才新建的example目录里
- 把Nginx配置替换为以下内容,重载配置即可:
server { listen 80; listen [::]:80; server_name localhost; location /example { alias /usr/share/nginx/html/example; index index.html index.htm; try_files $uri $uri/ /example/index.html; } # 可选配置:访问根路径时自动跳转到/example子站点 location = / { return 302 /example; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
注意:子路径映射一定要用
alias而不是root,root会把location匹配的路径段拼接到文件查找路径前,会导致路径重复找不到文件,alias会直接把匹配到的路径映射到指定目录,不会出现路径拼接错误。
方案2:修改React打包配置,用相对路径
如果你不想调整服务器上的文件目录结构,直接修改package.json里的homepage字段值为"./",重新执行npm run build打包,把新生成的build产物覆盖到/usr/share/nginx/html目录即可。这种方式打包出来的静态资源都是相对路径引用,不依赖固定前缀,部署在任意子路径都能正常加载,Nginx沿用你之前调整后的配置(引入mime.types、配置根路径try_files)就可以正常运行。
你最初配置里单独匹配.css、.js后缀手动加Content-Type的规则完全没必要,只要在http块或者server块里引入mime.types,Nginx会自动根据文件后缀返回正确的Content-Type响应头,手动写匹配规则反而可能因为规则优先级问题覆盖默认配置,引发异常。
内容的提问来源于stack exchange,提问作者Michael

