在 nginx 中,try_files 和 rewrite 联合使用的核心在于利用 try_files 的“回退”机制触发重定向。具体做法是将静态文件路径放在 try_files 列表的前面,当所有静态路径都匹配失败时,将最后一个参数设置为一个以 = 或 ^~ 开头的内部重定向(如 =/index.php),这会立即终止当前上下文并跳转到指定的 uri,从而绕过后续的 rewrite 规则或进入 php-fpm 处理流程。

如何配置 SPA 前端路由的回退逻辑
对于 Vue、React 等单页应用,浏览器刷新非根路径时会请求服务器不存在的静态文件。此时需要让 Nginx 尝试查找该文件,若找不到则统一返回入口 HTML 文件。通过设置 try_files $uri $uri/ /index.html;,Nginx 会依次检查文件是否存在,最后一步直接内部跳转到 /index.html,确保前端路由正常工作。

server {
listen 80;
server_name example.com;
root /var/www/html;
# 核心配置:先找文件,再找目录,最后回退到 index.html
location / {
try_files $uri $uri/ /index.html;
}
}
预期结果:访问 /about 时,若 /var/www/html/about 不存在且不是目录,Nginx 内部跳转至 /index.html,浏览器地址栏保持 /about,前端 JS 接管渲染。
如何将动态请求与静态资源隔离处理
当网站同时包含静态资源和动态脚本(如 PHP)时,需避免静态请求被错误地交给后端处理。可以在 location 块中使用 try_files 优先匹配静态资源,失败后通过 rewrite 或内部跳转将请求转发给 FastCGI。关键在于使用 =404 或明确的内部 URI 作为 try_files 的兜底项,防止无限循环。

server {
listen 80;
server_name example.com;
root /var/www/html;
location / {
# 如果文件存在,直接返回;否则内部跳转到 /index.php
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 针对特定动态路径的重写示例
location /api {
rewrite ^/api/(.*)$ /index.php?route=$1 last;
}
}
预期结果:访问 /style.css 直接返回文件;访问 /api/user 触发 rewrite 规则,将请求重写为 /index.php?route=user 并交由 PHP 处理;访问不存在的 /nonexistent 返回 404。
try_files 兜底参数使用内部重定向时的行为差异
在 try_files 的最后一个参数中,如果使用 /fallback.html(无前缀),Nginx 会执行内部子请求,重新经过 location 匹配,可能导致递归或意外触发其他 rewrite 规则。而使用 =/fallback.html(带等号)则直接设置响应头和 URI,跳过后续所有匹配逻辑。这种差异在处理复杂路由或多层嵌套时至关重要,开发者应根据是否需要再次匹配来选择前缀。











