4.1 核心概念
- index
- 当请求指向一个目录时,Nginx 依次尝试的默认文件名,如
index index.html index.htm;。找到就返回它。 - autoindex
- 目录下没有 index 文件时,是否自动生成一个文件列表页面。
autoindex on;打开,常用于下载站;生产站点通常关闭以免暴露文件结构。 - MIME 类型(MIME Type)
- 告诉浏览器文件是什么类型的标识,如
text/html、application/json。Nginx 靠mime.types按扩展名映射,写进响应的 Content-Type。 - gzip 压缩
- 发送前用 gzip 算法压缩文本类响应(HTML/CSS/JS/JSON),显著减小传输体积。浏览器通过
Accept-Encoding声明支持,Nginx 据此决定是否压缩。 - expires / Cache-Control
- 缓存头。告诉浏览器"这个资源多久内可以直接用本地副本,不必再问服务器"。对带哈希指纹的静态资源可设很长。
- try_files
- 按顺序尝试多个路径,用第一个存在的;全都不存在则走最后的兜底(内部跳转或返回状态码)。SPA 路由回退的关键指令。
4.2 最简静态站点
server {
listen 80;
server_name static.example.com;
root /var/www/site;
# 目录请求时依次找这些文件
index index.html index.htm;
location / {
# 找不到文件返回 404,而不是目录列表
try_files $uri $uri/ =404;
}
}
4.3 autoindex:目录列表(下载站)
location /files/ {
alias /data/public/;
autoindex on; # 生成文件列表
autoindex_exact_size off; # 显示人类可读大小(KB/MB)
autoindex_localtime on; # 用本地时间显示修改时间
}
autoindex 是把双刃剑
它方便做简易文件服务器,但也会暴露目录下所有文件名。业务站点务必保持默认关闭;确需开启,只对特定下载目录开,并搭配访问控制(第 9 章)。
4.4 gzip 压缩
http {
gzip on;
gzip_comp_level 5; # 1-9,越高压得越狠也越费 CPU,5 是平衡点
gzip_min_length 1024; # 小于 1KB 不压缩(没意义)
gzip_vary on; # 加 Vary: Accept-Encoding,利于缓存正确
gzip_proxied any; # 代理请求也压缩
gzip_types
text/plain text/css application/json
application/javascript text/xml
application/xml image/svg+xml;
}
别压已经压过的东西
图片(JPG/PNG/WebP)、视频、字体 woff2 本身已是压缩格式,再 gzip 几乎不会更小,反而白费 CPU。所以 gzip_types 只列文本类。更进一步可用 ngx_brotli 模块,压缩率比 gzip 更高。
4.5 缓存头 expires
# 带哈希指纹的资源(app.3f2a.js)可长期缓存
location ~* \.(js|css|woff2|png|jpg|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# HTML 入口文件不能长缓存,否则更新不生效
location = /index.html {
expires -1; # 每次都校验
add_header Cache-Control "no-cache";
}
策略要点:文件名带哈希的资源(内容变则文件名变)可以放心 expires 1y 甚至 immutable;而 index.html 这类入口文件绝不能长缓存,否则用户拿到旧 HTML、引用不到新资源。
4.6 try_files 与 SPA 路由回退
单页应用(React/Vue)的前端路由(如 /user/123)在服务器上并没有对应文件。刷新页面时若直接找文件会 404。try_files 解决这个问题:
location / {
# 依次尝试:文件 → 目录 → 回退到 index.html 交给前端路由
try_files $uri $uri/ /index.html;
}
请求 /user/123 时:$uri(无此文件)→ $uri/(无此目录)→ 回退返回 /index.html,前端 JS 接管路由。这是部署 SPA 最关键的一行。
4.7 自定义错误页
server {
# 把 404 指向自定义页面
error_page 404 /404.html;
location = /404.html {
root /var/www/errors;
internal; # 只能内部跳转到达,不能被外部直接请求
}
# 5xx 统一到一个维护页
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/errors;
internal;
}
}
4.8 sendfile 与静态性能
http {
sendfile on; # 零拷贝:内核直接把文件送到 socket,不经用户态
tcp_nopush on; # 攒满一个包再发,配合 sendfile 提升吞吐
tcp_nodelay on; # 长连接下小包立即发,降低延迟
open_file_cache max=10000 inactive=60s; # 缓存文件描述符/元信息
}
sendfile 为什么快
传统发文件要经历"磁盘 → 内核缓冲 → 用户态缓冲 → 内核 socket 缓冲 → 网卡"多次拷贝。sendfile 让数据在内核态直接从文件描述符流向 socket,省去用户态来回拷贝,这就是 Nginx 发静态文件极快的底层原因。
4.9 小结与下一步
- index 定义目录默认文件;autoindex 生成列表(生产慎开)。
- gzip 只压文本类;带哈希的资源长缓存,index.html 用 no-cache。
try_files $uri $uri/ /index.html是 SPA 部署的灵魂一行。- error_page + internal location 做优雅的自定义错误页。
- sendfile 零拷贝 + tcp_nopush 让静态服务快到极致。
- 下一章进入 Nginx 的另一半灵魂——反向代理。