nginx静态资源分发关键在于正确使用location修饰符:优先用^~匹配明确路径前缀(如/static/),再用~*统一处理后缀,=用于精确匹配,/兜底放最后;匹配按优先级而非配置顺序。

要让静态资源(如 CSS、JS、图片)被 Nginx 正确拦截并高效分发,关键不是把规则写得“靠前”,而是用对 location 修饰符 和匹配逻辑。Nginx 不按配置顺序选 location,而是严格按优先级分两阶段匹配:先找最优前缀,再决定是否进正则。
静态资源优先用 ^~ 前缀匹配
对 /static/、/assets/、/images/ 这类明确路径前缀的静态目录,必须用 ^~ 修饰符。它一匹配就停止后续所有正则检查,避免被后面的 ~ \.js$ 等规则干扰或覆盖。
-
location ^~ /static/ { root /var/www/app; }→ 匹配/static/css/app.css,且不进入任何正则分支 - 别写成
location /static/ { ... }(普通前缀),它优先级低于正则,可能被location ~ \.css$截胡,导致 root 路径错乱 - 若同时有
^~ /static/和^~ /static/js/,后者更长,会优先生效 —— 符合最长前缀原则
文件后缀统一用 ~* 正则匹配
针对通用后缀(如 .jpg、.png、.woff2),推荐用 ~*(不区分大小写),放在 ^~ 块之后、普通前缀之前。注意:它只在第一阶段没命中 = 或 ^~ 时才参与匹配。
location ~* \.(js|css|png|jpg|gif|svg|woff2|ttf)$ { expires 1y; add_header Cache-Control "public, immutable"; }- 确保这类正则不写在
^~块前面 —— 即使位置靠前,^~仍会短路它;但若误写在=前面,也无影响,因为=优先级更高 - 不要为同一类后缀写多个
~和~*,避免顺序依赖;一个~*覆盖全部更清晰
避免常见陷阱:精确匹配与根路径兜底
首页、favicon.ico 等固定资源适合 = 精确匹配;而 location / 必须放最后,作为兜底,否则会提前截断其他规则。
-
location = /favicon.ico { alias /var/www/static/favicon.ico; log_not_found off; }→ 只响应/favicon.ico,不带查询参数也不带斜杠 -
location = / { return 200 "Home"; }和location / { proxy_pass http://backend; }可共存,前者优先生效 - 删掉冗余的
location / { ... },除非真需要全局兜底;多数情况应由更具体的规则覆盖
验证是否生效:看实际匹配路径而非配置顺序
Nginx 不记录“为什么选这个 location”,但可通过日志或调试确认行为。加一句 add_header X-Location-Match "static-prefix"; 到各块中,用 curl 查看响应头即可快速定位。
- 请求
/static/logo.png→ 应看到X-Location-Match: static-prefix,而不是regex-js-css - 请求
/api/v1/users→ 不该触发任何静态规则;若意外命中/或/api前缀,说明缺少更精确的^~ /api/或= /api - 用
nginx -t检查语法,再nginx -s reload生效;改完务必测试真实 URI,别只看配置结构











