Nginx重写规则不生效,总是返回404怎么办?

码农怡平 阅读 47

我用Nginx部署了一个前端项目,想把所有非静态资源的请求都重写到index.html,但配置了rewrite后刷新页面还是404。

我试过在location里加rewrite ^(.*)$ /index.html last;,也试过用try_files,但都不行。这是我的配置:

location / {
    root /usr/share/nginx/html;
    rewrite ^(.*)$ /index.html last;
}
我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
UI子骞
UI子骞 Lv1
你这个配置有个致命问题:rewrite 会把所有请求(包括 /api、/favicon.ico、/static/xxx.js 这些)都重写到 index.html,但 Nginx 在 rewrite 后还会继续处理,而 /index.html 本身又匹配当前 location,导致死循环或者提前终止,最终返回 404。

正确做法是用 try_files,而且要先判断静态文件是否存在,不存在再回退到 index.html,比如这样:

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


注意:
- $uri 是当前请求的文件路径,Nginx 会优先找这个真实文件
- 如果文件不存在(比如 /user/123 这种前端路由),再走 /index.html
- 千万别用无条件 rewrite,容易被恶意路径绕过,比如 /../../etc/passwd 这类注入,try_files 会自动做路径安全校验,防止注入

另外检查下 index.html 是否真的在 /usr/share/nginx/html 下,权限是不是 644,目录是不是 755,有时候问题出在文件根本没放对位置或者 Nginx 没读权限。
点赞 1
2026-02-24 03:03
Good“庆玲
你这个配置的问题在于 rewrite 的位置不对,而且规则太宽泛了。
官方文档里说,rewrite 如果放在 location 根块里,会先于 try_files 执行,但你这里没加 try_files,而且所有请求(包括 /api/xxx 这种)都被重写了,静态资源也可能被干扰。

正确做法是:先尝试找真实文件,找不到再回退到 index.html,用 try_files 就行,不用 rewrite。

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


注意:
- $uri 是当前请求的文件路径,比如 /about
- $uri/ 是加上斜杠后的目录路径(比如 /about/)
- 如果这两个都不存在,就返回 /index.html,让前端路由接管

别再用 rewrite ^(.*)$ /index.html last; 这种通杀规则了,容易把自己绕进去。
如果你确实有 API 接口要单独处理,记得把 location /api/ 单独拎出来,别让它进这个 fallback 逻辑里。
点赞 3
2026-02-23 22:03