Skip to content

静态资源、缓存与 HTTPS

这篇笔记聚焦 Nginx 另外一条非常常见的主线:

  1. 静态资源分发
  2. 缓存控制
  3. 压缩优化
  4. HTTPS 入口

很多团队前面放 Nginx,不只是为了代理接口,更是为了把“资源交付”和“统一接入”这类问题集中处理。


1. 为什么静态资源经常交给 Nginx

这里的 静态资源 指的是:内容不会因为每次请求而动态计算的文件,例如 HTML、CSS、JavaScript、图片、字体文件。

Nginx 很适合处理这类资源,原因通常有:

  1. 分发静态文件效率高
  2. 配置缓存头方便
  3. 适合统一处理压缩和响应头
  4. 很容易和前端构建产物、CDN 配合

如果是前后端分离项目,常见链路通常是:

  1. 前端打包生成静态文件
  2. 文件部署到 Nginx 可访问目录
  3. Nginx 直接返回这些资源
  4. API 请求再代理到后端服务

2. 单页应用为什么刷新容易 404

这在前端项目里非常常见。

原因不是前端路由失效,而是:浏览器刷新时,会把当前路径当成真实 URL 发给服务端。

例如访问:/user/profile

如果服务端目录里没有这个真实文件路径,就会返回 404

这时 Nginx 常见的兜底配置是:

nginx
location / {
  root /var/www/app;
  try_files $uri $uri/ /index.html;
}

这里的 try_files 可以理解成 先按顺序尝试找真实文件,找不到时回退到指定文件

这段配置的含义是:

  1. 先尝试找当前路径对应的静态文件
  2. 如果没有,就返回 index.html
  3. 再由前端路由接管页面渲染

3. 缓存头到底在解决什么问题

缓存头 可以理解成 服务端通过响应头告诉浏览器,这些资源能不能缓存、缓存多久、什么时候重新验证

它解决的是:

  1. 浏览器重复下载相同资源
  2. 页面访问慢
  3. 源站压力大

对于前端构建后的带 hash 文件,例如:app.8f3a2d1.js

更常见的做法是给它们配置长期缓存,因为文件名一旦变化,就意味着内容也变了。

例如:

nginx
location /assets/ {
  root /var/www/app;
  expires 30d;
  add_header Cache-Control "public, max-age=2592000, immutable";
}

这里的 immutable 可以看成 告诉浏览器:这个文件名一旦命中,一般不需要频繁重新校验,因为文件内容预期不会变化


4. gzip 压缩是什么,为什么常放在 Nginx 开

gzip 是一种压缩响应体体积的方式。

它解决的是:

  1. 文本资源体积大
  2. 网络传输慢
  3. 页面首屏加载时间长

Nginx 很适合统一处理压缩,因为它就在流量入口层。

例如:

nginx
gzip on;
gzip_types text/plain text/css application/javascript application/json application/xml;
gzip_min_length 1024;

这段配置可以这样理解:

  1. 开启 gzip
  2. 只压缩指定类型的文本类响应
  3. 太小的响应体不压缩,避免压缩开销大于收益

5. HTTPS 是什么,为什么常终止在 Nginx

HTTPS 可以理解成 在 HTTP 之上增加 TLS 加密,让浏览器和服务端之间的通信更安全

这里的 TLSTransport Layer Security,可以理解成:

负责建立加密连接、保护传输内容不被窃听和篡改的一套安全协议。

很多团队会把 HTTPS 终止在 Nginx,意思是:

  1. 浏览器和 Nginx 之间走 HTTPS
  2. TLS 握手和证书管理集中在 Nginx
  3. Nginx 再把请求转发给后端

这么做的好处通常有:

  1. 统一证书管理
  2. 简化后端服务配置
  3. 便于统一做 HTTP 跳转 HTTPS
  4. 更适合作为统一入口治理

6. 一个常见的 HTTPS 配置骨架

nginx
server {
  listen 80;
  server_name example.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name example.com;

  ssl_certificate     /etc/nginx/ssl/example.crt;
  ssl_certificate_key /etc/nginx/ssl/example.key;

  location / {
    root /var/www/app;
    try_files $uri $uri/ /index.html;
  }

  location /api/ {
    proxy_pass http://app_backend;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

这段配置对应的思路是:

  1. 所有 HTTP 请求先跳到 HTTPS
  2. 443 端口承接加密连接
  3. 静态页面由 Nginx 直接返回
  4. API 请求继续代理到后端服务

7. CDN、Nginx 和源站之间是什么关系

这里也很容易混。

可以这样理解:

  1. CDN:负责把内容分发到更靠近用户的边缘节点
  2. Nginx:负责源站入口、静态资源交付、代理与缓存规则
  3. 源站:真正存放内容或提供服务的后端系统

很多架构里,关系会是:用户 -> CDN -> Nginx -> 应用服务

或者:用户 -> CDN -> OSS / Nginx

所以 Nginx 不等于 CDN,但两者经常协同工作。


8. 工程上最常见的几个误区

8.1 误区一:所有资源都一股脑长期缓存

不行。

如果资源文件名不稳定,却又给了很长缓存时间,浏览器可能长时间拿到旧内容。

8.2 误区二:把 gzip 当成所有内容都该开

二进制资源例如图片、视频很多时候本身已经压缩过,再做 gzip 未必有收益。

8.3 误区三:HTTPS 配好了证书就结束了

真正的入口治理还常常包括:

  1. HTTP 强制跳转 HTTPS
  2. 透传原始协议头
  3. 证书更新与续期
  4. 混合内容问题排查

这里的 混合内容 指的是:页面本身走 HTTPS,但页面里又引用了 HTTP 资源。

这会导致浏览器安全告警,甚至直接拦截资源。


9. 一句话总结

Nginx 在静态资源、缓存与 HTTPS 这条主线上,解决的核心问题是:

如何更高效地交付前端资源,如何减少重复请求和传输开销,以及如何把安全接入和证书管理统一收敛到入口层。

基于 VitePress 构建的个人技术笔记。