Nginx 通过 location 规则实现动静分离:匹配 .php 请求交由 FastCGI 处理,其余请求由 Nginx 直接服务静态资源;关键在于规则优先级与 root/alias 的正确使用。

Nginx 通过 FastCGI 实现动态与静态请求分离,本质仍是“动静分离”的一种具体落地方式——静态资源由 Nginx 直接读取返回,PHP 等动态脚本交由 FastCGI 进程(如 php-fpm)处理。关键不在于 FastCGI 本身做分离,而在于 Nginx 的 location 规则如何精准匹配、分流请求。
FastCGI 场景下动静分离的核心逻辑
Nginx 不会自动识别“哪个是动态、哪个是静态”,它只按配置规则执行:
- 匹配到
location ~ \.php$这类规则 → 交给fastcgi_pass处理(即走 PHP 动态流程) - 其他未被特殊规则捕获的请求(如
/style.css、/images/logo.png、/index.html)→ 默认走root+index路径,由 Nginx 直接服务
这就天然形成了分离:FastCGI 只负责 .php 请求,其余都是静态路径。
关键配置要点
-
静态资源必须能被 location 规则“放过”
不要让
location /拦截所有请求后又漏掉.php;更推荐显式声明静态路径优先级-
常见可靠写法:
location / { root /var/www/html; index index.html index.htm index.php; # index.php 仅作默认入口,不触发 FastCGI } # 静态文件后缀直接由 Nginx 返回(可选,增强控制) location ~* \.(css|js|png|jpg|gif|ico|woff2|svg)$ { root /var/www/html; expires 1y; add_header Cache-Control "public, immutable"; } # 仅 .php 请求交由 php-fpm location ~ \.php$ { root /var/www/html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
-
注意
root和alias的作用范围差异-
root是拼接路径:root /var/www;+location /static/→ 实际找/var/www/static/xxx -
alias是替换路径:alias /var/www/assets/;+location /static/→ 实际找/var/www/assets/xxx - 若静态资源放在子目录(如
/static/),用alias更清晰,避免重复路径
-
-
HTML 文件要不要当静态处理?
- 如果是纯前端打包产物(Vue/React 的
dist/),应归为静态,可用:location / { root /var/www/dist; try_files $uri $uri/ /index.html; # 支持前端路由 } - 如果 HTML 含 PHP 模板(如
index.php渲染),就仍走 FastCGI,不能try_files到.html
- 如果是纯前端打包产物(Vue/React 的
-
避免常见陷阱
-
location ~ \.php$写在location /后面?没问题,因为正则 location 优先级高于前缀 location - 但若写了
location ^~ /api/却没配proxy_pass,反而会拦截 API 请求导致 404 -
fastcgi_param SCRIPT_FILENAME必须指向真实磁盘路径,否则 php-fpm 找不到文件报 502
-
总结一句话
FastCGI 本身不调度、不分流,它只是 Nginx 转发给 PHP 的一个通道;真正的分离调度,全靠 location 的匹配顺序和指令组合——把 .php 显式交给 FastCGI,其余都留给 Nginx 自己读文件,就是最简、最稳的动静分离。


















