ToolkitX
知识库工具箱

静态文件服务

配置静态文件、目录索引、gzip

15min·入门

01. 静态文件服务配置

Nginx 最基础的功能就是当静态文件服务器——直接返回 HTML、CSS、JS、图片等文件给浏览器。不需要后端程序参与,Nginx 直接从磁盘读了发出去。 核心指令: root——指定文件根目录。比如 root /var/www/html;,访问 example.com/logo.png 就找 /var/www/html/logo.png。 alias——跟 root 类似但能路径重写。比如 alias /var/static/; 访问 /images/logo.png 变成 /var/static/logo.png(不带 images 前缀)。 index——默认文件,访问目录时找哪个文件(如 index.html)。 try_files——按照顺序尝试文件,找不到就返回某个 URI(常用于单页应用的路由回调)。 autoindex on——开启目录浏览,浏览器能直接看到目录的文件列表(像 FTP)。生产环境通常是 off(安全考虑)。
nginx
server {
  listen 80;
  server_name example.com;
  root /var/www/html;
  index index.html index.htm;

  location / {
    try_files $uri $uri/ =404;
  }

  # 图片文件单独配置缓存
  location ~* \.(jpg|png|gif|svg|ico)$ {
    expires 30d;
    add_header Cache-Control "public";
  }
}
root 和 alias 容易搞混——root 会拼接 URI 路径,alias 会替换 URI 前缀。静态文件服务用 root 就行,反向代理路径重写时才用 alias。

02. gzip 压缩——让文件传得更快

gzip 能在服务器端把文本文件(HTML、CSS、JS、JSON)压缩后再发给浏览器,压缩率通常 60%~80%。用户在浏览器上感觉不到压缩和解压的过程,但下载速度快了一大截。 关键配置: gzip on——开启压缩。 gzip_types——指定哪些文件类型要压缩。text/html 默认已包含。 gzip_min_length——小于这个字节数就不压缩了(太小的文件压了反而更慢)。 gzip_comp_level——压缩级别 1~9。1 最快但压得小,9 最慢但压得最好。推荐 5~6。 gzip_vary on——在响应头加 Vary: Accept-Encoding,告诉 CDN/缓存我支持压缩。 gzip_proxied——对反向代理来的响应也压缩。 注意:图片和视频已经压缩过了,再 gzip 没效果反而浪费 CPU。只压文本类文件。
nginx
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 256;
gzip_comp_level 5;
gzip_vary on;
gzip_proxied any;
gzip_disable "msie6";
几乎所有的前端项目都应该开 gzip。一般开启后文本资源能减少 60%~80% 的传输量。

03. 浏览器缓存策略

让浏览器缓存静态资源是提升加载速度最有效的方法之一——用户第二次访问你的网站,静态资源直接从浏览器缓存拿,不需要任何网络请求。 expires——告诉浏览器这个资源能缓存多久。expires 30d 就是缓存 30 天。 Cache-Control——比 Expires 更现代的缓存控制头。public 表示 CDN 也能缓存;immutable 表示这个文件不会变,别重新验证。 缓存策略: 不变的文件(带 hash 的 JS/CSS)→ 缓存一年,immutable 可能会变的文件(index.html)→ 不缓存或短期缓存 图片、字体 → 缓存一个月到一年 强缓存 vs 协商缓存:expires/Cache-Control 设置了强缓存——直接拿缓存不请求服务器。ETag/Last-Modified 是协商缓存——请求服务器但服务器说 304(没变直接用缓存)。
nginx
# 带 hash 的构建文件——长期缓存
location ~* \.[a-f0-9]{8,}\.(js|css)$ {
  expires 1y;
  add_header Cache-Control "public, immutable";
}

# 图片字体——中期缓存
location ~* \.(jpg|png|gif|svg|woff2|ttf)$ {
  expires 30d;
  add_header Cache-Control "public";
}

# HTML——短期缓存或不缓存
location / {
  expires -1;
  add_header Cache-Control "no-cache";
}
前端构建工具(Webpack、Vite)会给文件加 content hash——文件内容不变 hash 就不变。配合 immutable 让浏览器永久缓存这些文件。

04. CORS 跨域配置

浏览器的同源策略阻止一个域名的网页访问另一个域名的资源。CORS(跨域资源共享)通过在 HTTP 响应头里加许可来允许跨域访问。 Access-Control-Allow-Origin——允许哪些域名跨域访问。如果所有域名都能访问就写 *。 Access-Control-Allow-Methods——允许哪些 HTTP 方法(GET、POST、PUT 等)。 Access-Control-Allow-Headers——允许哪些请求头。 Access-Control-Allow-Credentials——是否允许带 Cookie 的跨域请求。如果设了 true,Access-Control-Allow-Origin 不能是 *。 OPTIONS 预检请求:浏览器在复杂请求前先发一个 OPTIONS 请求问服务器允不允许。Nginx 可以统一处理预检请求。
nginx
# 允许所有跨域(公开 API)
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";

# OPTIONS 预检请求直接返回 204
if ($request_method = 'OPTIONS') {
  return 204;
}

# 允许带 Cookie(指定具体域名)
add_header Access-Control-Allow-Origin https://example.com;
add_header Access-Control-Allow-Credentials true;
Access-Control-Allow-Origin 设为 * 时不能同时设 Allow-Credentials: true。如果需要带 Cookie 跨域,必须指定具体域名。

05. 单页应用(SPA)的 Nginx 配置

React、Vue 等单页应用的前端路由(如 /user/profile)在首次加载后由前端 JS 处理。但用户直接访问 /user/profile 或刷新页面时,Nginx 找不到对应的物理文件就返回 404。 解决方案:try_files $uri $uri/ /index.html; ——告诉 Nginx 如果找不到文件,就把请求交给 index.html。前端的路由系统再根据 URL 渲染对应的组件。 注意:API 请求不要被这条规则捕获。把 API 的 location 放前面匹配,try_files 放后面兜底。
nginx
server {
  listen 80;
  server_name example.com;
  root /var/www/spa;
  index index.html;

  # API 请求交给后端
  location /api/ {
    proxy_pass http://backend:3000;
  }

  # SPA 兜底
  location / {
    try_files $uri $uri/ /index.html;
  }
}
try_files 里的 /index.html 是 URI 而不是文件路径——Nginx 会用这个 URI 重新走一遍 location 匹配。所以 index.html 最终会由 root 指令找到。

知识测验

1/5正确 0

root 和 alias 指令的区别?

下一节

反向代理配置

下一节