前端面试第 78 期 - 2025.09.07 更新 Nginx 专题面试总结(12 道题)
2025.08.31 - 2025.09.07 更新前端面试问题总结(12 道题)
获取更多面试相关问题可以访问
github 地址: github.com/pro-collect…
gitee 地址: gitee.com/yanleweb/in…
目录:
中级开发者相关问题【共计 2 道题】
- SPA 的 history 路由模式在 Nginx 部署时刷新 404,如何配置解决【热度: 488】【web 应用场景】
- 如何通过 Nginx 配置前端静态资源的 “hash 资源永久缓存 + 非 hash 资源协商缓存”?【热度: 75】【web 应用场景】
高级开发者相关问题【共计 10 道题】
- Nginx 配置跨域(CORS)需设置哪些关键响应头?复杂跨域(带 cookie、自定义头)有何注意点【热度: 124】【web 应用场景】
- Nginx 中 proxy_pass 路径结尾加 / 与不加 /,对前端接口代理路径有何差异?举例说明。【热度: 106】【web 应用场景】
- Nginx 如何通过 include 或 vhost 实现前端多环境隔离?同域名不同路径映射需解决哪些重写问题?【热度: 112】【web 应用场景】
- Nginx 如何配置支持前端大资源的 Range 分片请求?核心参数是什么?【热度: 146】【web 应用场景】
- Nginx 如何按资源类型(如.js/.png)分发到不同服务器?配置策略是什么?【热度: 159】【web 应用场景】【出题公司: 阿里巴巴】
- Nginx 配置 gzip/brotli 压缩时需考虑哪些因素?为何不建议对所有前端资源开启压缩?【热度: 106】【web 应用场景】【出题公司: 阿里巴巴】
- 微前端通过 Nginx 实现主 / 子应用路由分发,如何配置 location 和 try_files?需处理哪些资源路径问题?【热度: 120】【web 应用场景】
- Nginx 配置 HTTPS 需哪些核心项(协议、加密套件)?如何强制 HTTP 跳转 HTTPS?【热度: 182】【web 应用场景】
- 前端静态资源加载超时,Nginx 可通过哪些配置优化?【热度: 190】【web 应用场景】【出题公司: 阿里巴巴】
- Nginx 如何为不同前端资源配置缓存策略?如何强制刷新特定资源?【热度: 110】【web 应用场景】
中级开发者相关问题【共计 2 道题】
1137. SPA 的 history 路由模式在 Nginx 部署时刷新 404,如何配置解决【热度: 488】【web 应用场景】
关键词:nginx 刷新 404
要解决 SPA(单页应用)History 路由模式在 Nginx 部署时刷新 404 的问题,核心是理解 History 路由的原理缺陷 与 Nginx 的请求匹配逻辑,再通过针对性配置让所有路由请求都指向 SPA 的入口文件(通常是 index.html
)。以下是完整解决方案:
一、问题根源:为什么会出现 404?
首先要明确 SPA 两种路由模式的本质差异,这是理解问题的关键:
路由模式 | 原理 | 部署后刷新行为 |
---|---|---|
Hash 模式(# ) |
路由信息包含在 URL 的 # 后(如 https://xxx.com/#/about ),# 后的内容不会发送给服务器,所有请求本质都是访问根路径(/ ) |
刷新时服务器只接收 / 请求,返回 index.html ,SPA 再解析 # 后的路由,不会 404
|
History 模式(无 # ) |
路由信息是真实 URL 路径(如 https://xxx.com/about ),刷新时浏览器会将完整路径(/about )发送给服务器 |
Nginx 会查找 /about 对应的物理文件/目录,而 SPA 只有 index.html 一个入口文件,找不到就返回 404
|
二、解决方案:Nginx 核心配置
核心思路:让 Nginx 接收到所有 SPA 路由相关的请求时,都返回入口文件 index.html
,由 SPA 框架(Vue/React/Angular 等)再解析具体路由。
1. 基础配置(通用版)
在 Nginx 的 server
块中,通过 try_files
指令实现“优先匹配物理文件,匹配不到则返回 index.html
”:
server {
listen 80; # 监听端口(根据实际情况调整,如 443 用于 HTTPS)
server_name your-domain.com; # 你的域名(如 localhost 用于本地测试)
root /path/to/your/spa; # SPA 打包后文件的根目录(绝对路径,如 /usr/local/nginx/html/spa)
index index.html; # 默认入口文件
# 关键配置:解决 History 路由刷新 404
location / {
# try_files 逻辑:先尝试访问 $uri(当前请求路径对应的物理文件)
# 再尝试访问 $uri/(当前请求路径对应的目录)
# 最后都找不到时,重定向到 /index.html(SPA 入口)
try_files $uri $uri/ /index.html;
}
}
2. 进阶配置(处理子路径部署)
如果 SPA 不是部署在域名根路径(如 https://xxx.com/admin
,而非 https://xxx.com
),需调整 location
匹配规则和 try_files
目标路径,避免路由错乱:
server {
listen 80;
server_name your-domain.com;
root /path/to/your/project; # 注意:这里是父目录(包含 admin 子目录)
index index.html;
# 匹配所有以 /admin 开头的请求(SPA 部署在 /admin 子路径)
location /admin {
# 1. 先尝试访问子路径下的物理文件(如 /admin/static/css/main.css)
# 2. 再尝试访问子路径下的目录
# 3. 最后重定向到 /admin/index.html(子路径下的入口文件,而非根目录)
try_files $uri $uri/ /admin/index.html;
# 可选:如果 SPA 框架需要 base 路径,需在框架配置中同步设置
# 例:Vue 需配置 publicPath: '/admin/',React 需配置 homepage: '/admin/'
}
}
三、注意事项(避坑点)
-
路径正确性:
-
root
指令必须指向 SPA 打包后文件的 实际绝对路径(如 Linux 下的/var/www/spa
,Windows 下的D:/nginx/html/spa
),错误路径会导致 Nginx 找不到index.html
。 - 子路径部署时,
try_files
最后一个参数必须是 完整的子路径入口(如 /admin/index.html),不能写/index.html
(会指向根目录,导致 404)。
-
-
HTTPS 场景适配: 如果网站使用 HTTPS(
listen 443 ssl
),配置逻辑完全一致,只需在server
块中补充 SSL 证书相关配置,不影响路由处理:server { listen 443 ssl; server_name your-domain.com; ssl_certificate /path/to/cert.pem; # SSL 证书路径 ssl_certificate_key /path/to/key.pem; # 证书私钥路径 root /path/to/your/spa; index index.html; location / { try_files $uri $uri/ /index.html; } }
-
配置生效方式: 修改 Nginx 配置后,需执行以下命令让配置生效(避免重启服务导致短暂 downtime):
# 1. 测试配置是否有语法错误(必须先执行,避免配置错误导致 Nginx 启动失败) nginx -t # 2. 重新加载配置(平滑生效,不中断现有连接) nginx -s reload
-
与后端接口的冲突处理: 如果 SPA 同时有后端接口请求(如
/api
开头的接口),需在 Nginx 中优先匹配接口路径,避免接口请求被转发到index.html
。配置示例:server { # ... 其他基础配置 ... # 第一步:优先匹配后端接口(/api 开头的请求),转发到后端服务 location /api { proxy_pass http://your-backend-server:port; # 后端服务地址(如 http://127.0.0.1:3000) proxy_set_header Host $host; # 传递 Host 头信息 proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端 IP } # 第二步:剩余请求(SPA 路由)转发到 index.html location / { try_files $uri $uri/ /index.html; } }
四、原理总结
通过 try_files $uri $uri/ /index.html
这行核心配置,Nginx 实现了:
- 优先处理 静态资源请求(如
css
、js
、img
):如果请求路径对应物理文件(如/static/css/main.css
),则直接返回该文件。 - 兜底处理 SPA 路由请求:如果请求路径不对应任何物理文件(如
/about
、/user/123
),则返回index.html
,由 SPA 框架根据 URL 解析并渲染对应的页面,从而解决刷新 404 问题。
1144. 如何通过 Nginx 配置前端静态资源的 “hash 资源永久缓存 + 非 hash 资源协商缓存”?【热度: 75】【web 应用场景】
关键词:nginx 资源缓存
要实现前端前端静态资源的“hash 资源永久缓存 + 非 hash 资源协商缓存”,需结合 Nginx 的缓存头配置,针对不同类型资源设计差异化策略。核心思路是:对带 hash 的指纹文件(如app.8f3b.js
)设置长期强缓存,对无 hash 的文件(如index.html
)使用协商缓存,既以下是具体实现方案:
一、两种缓存策略的适用场景
资源类型 | 特征 | 缓存策略 | 目的 |
---|---|---|---|
带 hash 的资源 | 文件名含唯一 hash(如style.1a2b.css ),内容变化则 hash 变化 |
永久强缓存 | 一次缓存后不再请求,减少重复下载 |
非 hash 的资源 | 文件名固定(如index.html 、favicon.ico ),内容可能动态更新 |
协商缓存 | 每次请求验证是否更新,确保获取最新内容 |
二、核心配置方案
通过location
匹配不同资源类型,分别设置缓存头:
server {
listen 80;
server_name example.com;
root /path/to/frontend/dist; # 前端打包目录
index index.html;
# 1. 处理带hash的静态资源(JS/CSS/图片等):永久强缓存
# 假设hash格式为 8-16位字母数字(如 app.8f3b1e7d.js)
location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff2?)(\?.*)?$ {
# 匹配带hash的文件名(如 .1a2b3c. 或 .v2.3.4. 等格式)
# 正则说明:\.\w{8,16}\. 匹配 .hash. 结构(8-16位hash值)
if ($request_filename ~* .*\.\w{8,16}\.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff2?)$) {
# 永久缓存(1年)
expires 365d;
# 强缓存标识:告知浏览器直接使用缓存,不发请求
add_header Cache-Control "public, max-age=31536000, immutable";
}
}
# 2. 处理非hash资源(如 index.html):协商缓存
location / {
# 禁用强缓存
expires -1;
# 协商缓存:基于文件修改时间(Last-Modified)验证
add_header Cache-Control "no-cache, must-revalidate";
# 支持 History 路由(SPA必备)
try_files $uri $uri/ /index.html;
}
# 3. 特殊资源补充:favicon.ico(通常无hash)
location = /favicon.ico {
expires 7d; # 短期强缓存(7天)+ 协商缓存兜底
add_header Cache-Control "public, max-age=604800, must-revalidate";
}
}
三、配置详解与核心参数
1. 带 hash 资源的永久强缓存
-
匹配规则:
通过正则.*\.\w{8,16}\.(js|css...)
精准匹配带 hash 的文件(如app.8f3b1e7d.js
、logo.a1b2c3.png
),确保只有内容不变的文件被长期缓存。 -
核心缓存头:
-
expires 365d
:设置浏览器缓存过期时间(1 年)。 -
Cache-Control: public, max-age=31536000, immutable
:-
public
:允许中间代理(如 CDN)缓存。 -
max-age=31536000
:1 年内直接使用缓存(单位:秒)。 -
immutable
:告知浏览器资源不会变化,无需发送验证请求(H5 新特性,增强缓存效果)。
-
-
-
关键逻辑:
当资源内容更新时,打包工具(Webpack/Vite 等)会生成新的 hash 文件名(如app.9c4d2f8e.js
),浏览器会将其视为新资源重新请求,完美解决“缓存更新”问题。
2. 非 hash 资源的协商缓存
-
适用场景:
index.html
(SPA 入口文件)、robots.txt
等文件名固定的资源,需确保用户能获取最新版本。 -
核心缓存头:
-
expires -1
:禁用强缓存(立即过期)。 -
Cache-Control: no-cache, must-revalidate
:-
no-cache
:浏览器必须发送请求到服务器验证资源是否更新。 -
must-revalidate
:若资源过期,必须向服务器验证。
-
-
-
协商验证机制:
Nginx 默认会返回Last-Modified
头(文件最后修改时间),浏览器下次请求时会携带If-Modified-Since
头:- 若文件未修改,服务器返回
304 Not Modified
(无响应体),浏览器使用缓存。 - 若文件已修改,服务器返回
200 OK
和新内容。
- 若文件未修改,服务器返回
3. 特殊资源处理(如 favicon.ico)
- 对于不常变化但无 hash 的资源(如网站图标),可采用“短期强缓存 + 协商缓存兜底”:
-
expires 7d
:7 天内直接使用缓存。 -
must-revalidate
:过期后必须向服务器验证是否更新。
-
四、与前端打包的配合要点
-
确保 hash 生成规则可靠:
前端打包时,需保证“内容不变则 hash 不变,内容变化则 hash 必变”。例如:- Webpack:
contenthash
(基于文件内容生成 hash)。 - Vite:默认对静态资源生成 contenthash。
- Webpack:
-
避免 hash 资源依赖非 hash 资源:
确保带 hash 的 JS/CSS 不引用无 hash 的资源(如background: url(/img/bg.png)
),否则 bg.png 更新后,引用它的 CSS 因 hash 未变而无法更新。
解决方案:让被引用资源也带上 hash(如bg.a1b2c3.png
)。 -
index.html 必须无 hash:
作为入口文件,index.html
需通过协商缓存确保用户每次获取最新版本,从而加载新的 hash 资源。
五、验证缓存是否生效
-
强缓存验证:
访问带 hash 的资源(如app.8f3b.js
),在浏览器 Network 面板中查看:- 状态码为
200 OK (from disk cache)
或200 OK (from memory cache)
。 - Response Headers 包含
Cache-Control: public, max-age=31536000, immutable
。
- 状态码为
-
协商缓存验证:
访问index.html
,刷新页面:- 第一次请求:状态码
200 OK
,Response Headers 有Last-Modified
。 - 第二次请求:Request Headers 有
If-Modified-Since
,若未修改,状态码304 Not Modified
。
- 第一次请求:状态码
总结
通过 Nginx 实现“hash 资源永久缓存 + 非 hash 资源协商缓存”的核心是:
- 利用 hash 文件名的唯一性,对静态资源设置长期强缓存,最大化减少重复请求。
- 对入口文件等无 hash 资源启用协商缓存,确保内容更新时能被及时获取。
- 前端打包与 Nginx 配置协同,保证 hash 机制可靠,避免缓存不一致问题。
这种策略既能大幅提升页面加载速度,又能确保资源更新的即时性,是前端性能优化的关键实践。
高级开发者相关问题【共计 10 道题】
1138. Nginx 配置跨域(CORS)需设置哪些关键响应头?复杂跨域(带 cookie、自定义头)有何注意点【热度: 124】【web 应用场景】
关键词:nginx 配置跨域
Nginx 配置跨域(CORS)的核心是通过设置特定响应头,允许不同域的前端资源请求当前服务器资源。以下是关键配置和复杂跨域场景的注意事项:
一、基础跨域配置:关键响应头
基础跨域(无 cookie、无自定义头)需配置以下核心响应头,允许指定域的请求访问资源:
location / {
# 1. 允许的源域名(必填)
# 注意:生产环境建议明确指定域名(如 https://example.com),而非 *
add_header Access-Control-Allow-Origin *;
# 2. 允许的请求方法(必填)
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
# 3. 允许的请求头(可选,根据实际需求添加)
add_header Access-Control-Allow-Headers 'Content-Type, Authorization';
# 4. 预检请求(OPTIONS)的缓存时间(可选,减少预检请求次数)
add_header Access-Control-Max-Age 3600;
# 处理预检请求(OPTIONS):直接返回 204 成功状态
if ($request_method = 'OPTIONS') {
return 204;
}
}
各头字段作用:
-
Access-Control-Allow-Origin
:指定允许跨域请求的源(*
表示允许所有源,不推荐生产环境使用)。 -
Access-Control-Allow-Methods
:允许的 HTTP 方法(需包含实际使用的方法,如OPTIONS
是预检请求必须的)。 -
Access-Control-Allow-Headers
:允许请求中携带的自定义头(如Authorization
、X-Custom-Header
)。 -
Access-Control-Max-Age
:预检请求(OPTIONS)的结果缓存时间(秒),避免频繁预检。
二、复杂跨域场景:带 cookie、自定义头的注意点
当跨域请求需要 携带 cookie 或 自定义请求头 时,配置需更严格,且前后端需协同配合:
1. 带 cookie 的跨域(withCredentials: true
)
-
Nginx 必须明确指定允许的源(不能用
*
),否则浏览器会拒绝响应:# 错误:带 cookie 时不能用 * # add_header Access-Control-Allow-Origin *; # 正确:明确指定允许的源(如 https://frontend.com) add_header Access-Control-Allow-Origin https://frontend.com; # 必须添加:允许携带 cookie add_header Access-Control-Allow-Credentials true;
-
前端需配合设置:请求时需显式开启
withCredentials
(以 Fetch 为例):fetch("https://backend.com/api/data", { credentials: "include", // 等价于 XMLHttpRequest 的 withCredentials: true });
2. 带自定义请求头(如 X-Token
)
-
需在
Access-Control-Allow-Headers
中显式包含自定义头,否则预检请求会失败:# 例如允许 X-Token、X-User-Id 等自定义头 add_header Access-Control-Allow-Headers 'Content-Type, X-Token, X-User-Id';
-
浏览器会先发送 OPTIONS 预检请求,需确保 Nginx 正确处理(返回 204 或 200):
if ($request_method = 'OPTIONS') { return 204; # 预检请求成功,无需返回 body }
3. 其他注意事项
-
add_header
指令的作用域:如果 Nginx 配置中存在多个location
块,跨域头需配置在对应请求的location
中(如接口请求通常在/api
路径)。 -
避免重复设置头:如果后端服务(如 Node.js、Java)已设置 CORS 头,Nginx 无需重复添加,否则可能导致浏览器解析冲突。
-
生产环境安全性:
- 禁止使用
Access-Control-Allow-Origin: *
(尤其是带 cookie 的场景)。 - 限制
Access-Control-Allow-Methods
为必要的方法(如仅允许GET, POST
)。 - 避免
Access-Control-Allow-Headers
包含通配符(如*
),仅添加实际需要的头。
- 禁止使用
三、完整复杂跨域配置示例(带 cookie + 自定义头)
server {
listen 80;
server_name backend.com;
# 接口路径的跨域配置(假设接口都在 /api 下)
location /api {
# 明确允许的前端域名(不能用 *)
add_header Access-Control-Allow-Origin https://frontend.com;
# 允许携带 cookie
add_header Access-Control-Allow-Credentials true;
# 允许的方法(包含预检请求 OPTIONS)
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
# 允许的头(包含自定义头 X-Token)
add_header Access-Control-Allow-Headers 'Content-Type, Authorization, X-Token';
# 预检请求结果缓存 1 小时
add_header Access-Control-Max-Age 3600;
# 处理预检请求
if ($request_method = 'OPTIONS') {
return 204;
}
# 转发请求到后端服务(如 Node.js、Java 服务)
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
}
}
总结
- 基础跨域:核心配置
Access-Control-Allow-Origin
、-Methods
、-Headers
。 - 带 cookie 跨域:必须指定具体
Origin
,并添加Access-Control-Allow-Credentials: true
。 - 自定义头跨域:需在
Allow-Headers
中显式声明,并正确处理 OPTIONS 预检请求。 - 生产环境需严格限制允许的源、方法和头,避免安全风险。
1139. Nginx 中 proxy_pass 路径结尾加 / 与不加 /,对前端接口代理路径有何差异?举例说明。【热度: 106】【web 应用场景】
关键词:nginx proxy_pass
Nginx 中 proxy_pass
路径结尾是否加 /
会直接影响代理后的 URL 拼接规则,对前端接口请求路径的映射结果有显著差异。理解这一差异是配置接口代理的关键。
核心差异:路径拼接规则
假设:
- Nginx 配置的
location
匹配规则为/api
- 后端服务地址为
http://backend:3000
两种配置的区别如下:
proxy_pass 配置 |
拼接规则 | 最终代理地址 |
---|---|---|
不加 / :proxy_pass http://backend:3000
|
将 location 匹配的路径(/api )完整拼接到后端地址后
|
http://backend:3000 + /api + 剩余路径 |
加 / :proxy_pass http://backend:3000/
|
将 location 匹配的路径(/api )替换为 / ,仅拼接剩余路径 |
http://backend:3000 + / + 剩余路径 |
举例说明(前端请求路径对比)
假设前端发送请求:http://nginx-host/api/user/list
1. proxy_pass
不加 /
的情况
location /api {
# 后端地址末尾无 /
proxy_pass http://backend:3000;
}
- 匹配逻辑:
location /api
匹配到请求中的/api
部分 - 代理后地址:
http://backend:3000
+/api
+/user/list
→http://backend:3000/api/user/list
2. proxy_pass
加 /
的情况
location /api {
# 后端地址末尾有 /
proxy_pass http://backend:3000/;
}
- 匹配逻辑:
location /api
匹配到的/api
被替换为/
- 代理后地址:
http://backend:3000/
+/user/list
→http://backend:3000/user/list
扩展场景:location
带多级路径时
若 location
规则为 /api/v1
,请求路径为 http://nginx-host/api/v1/user/list
1. 不加 /
location /api/v1 {
proxy_pass http://backend:3000;
}
# 代理结果:http://backend:3000/api/v1/user/list
2. 加 /
location /api/v1 {
proxy_pass http://backend:3000/;
}
# 代理结果:http://backend:3000/user/list
特殊场景:proxy_pass
包含子路径
若 proxy_pass
不仅是域名/IP,还包含子路径(如 http://backend:3000/service
),加不加 /
的规则依然适用:
1. 后端路径不加 /
location /api {
proxy_pass http://backend:3000/service;
}
# 请求 /api/user → 代理到 http://backend:3000/serviceapi/user
# (注意:/api 被完整拼接,导致 service 和 api 连在一起,通常不符合预期)
2. 后端路径加 /
location /api {
proxy_pass http://backend:3000/service/;
}
# 请求 /api/user → 代理到 http://backend:3000/service/user
# (正确拼接:/api 被替换为 /,剩余路径 /user 拼接到 service/ 后)
总结
-
不加
/
:location
匹配的路径会被完整拼接到proxy_pass
地址后(适合后端接口路径与前端请求路径完全一致的场景)。 -
加
/
:location
匹配的路径会被替换为/
,仅将剩余路径拼接到proxy_pass
地址后(适合需要简化后端接口路径的场景)。
实际配置时,建议通过 curl
测试或查看后端日志确认代理结果,避免因路径拼接错误导致接口 404。
1140. Nginx 如何通过 include 或 vhost 实现前端多环境隔离?同域名不同路径映射需解决哪些重写问题?【热度: 112】【web 应用场景】
关键词:nginx 多环境隔离
Nginx 可以通过 include
指令或虚拟主机(vhost)实现前端多环境(如开发、测试、生产)的隔离部署,同时针对同域名不同路径的映射场景,需要处理路径重写和资源引用问题。以下是具体实现方案和注意事项:
一、通过 include 或 vhost 实现多环境隔离
多环境隔离的核心是为不同环境(如 dev
、test
、prod
)配置独立的 Nginx 规则,避免互相干扰。
1. 基于 include 指令的多环境配置(推荐)
适合单服务器部署多个环境,通过拆分配置文件实现隔离,便于维护。
目录结构:
nginx/
├── conf.d/
│ ├── common.conf # 公共配置(如日志、超时时间)
│ ├── frontend-dev.conf # 开发环境配置
│ ├── frontend-test.conf # 测试环境配置
│ └── frontend-prod.conf # 生产环境配置
└── nginx.conf # 主配置文件(通过 include 引入子配置)
主配置(nginx.conf):
http {
# 引入公共配置
include conf.d/common.conf;
# 引入各环境配置(按需启用,生产环境可注释 dev/test)
include conf.d/frontend-dev.conf;
include conf.d/frontend-test.conf;
include conf.d/frontend-prod.conf;
}
环境配置示例(frontend-dev.conf):
# 开发环境:监听 8080 端口
server {
listen 8080;
server_name localhost;
# 开发环境前端文件目录
root /path/to/frontend/dev;
index index.html;
# 开发环境特有的路由配置(如 History 模式支持)
location / {
try_files $uri $uri/ /index.html;
}
# 开发环境接口代理(指向开发后端)
location /api {
proxy_pass http://dev-backend:3000;
}
}
优势:
- 配置模块化,各环境规则独立,修改单个环境不影响其他环境。
- 可通过注释
include
语句快速切换生效的环境。
2. 基于虚拟主机(vhost)的多环境配置
适合通过不同域名/端口区分环境(如 dev.example.com
、test.example.com
)。
配置示例:
http {
# 开发环境(域名区分)
server {
listen 80;
server_name dev.example.com; # 开发环境域名
root /path/to/frontend/dev;
# ... 其他配置(路由、代理等)
}
# 测试环境(端口区分)
server {
listen 8081; # 测试环境端口
server_name localhost;
root /path/to/frontend/test;
# ... 其他配置
}
# 生产环境(HTTPS)
server {
listen 443 ssl;
server_name example.com; # 生产环境域名
root /path/to/frontend/prod;
# ... SSL 配置和其他生产环境特有的规则
}
}
优势:
- 环境边界清晰,通过域名/端口直接访问对应环境,适合团队协作。
- 可针对生产环境单独配置 HTTPS、缓存等高级特性。
二、同域名不同路径映射的重写问题及解决方案
当多个前端应用部署在同一域名的不同路径下(如 example.com/app1
、example.com/app2
),需要解决路径映射和资源引用的问题。
场景示例
- 应用 A 部署在
/app1
路径,文件目录为/var/www/app1
- 应用 B 部署在
/app2
路径,文件目录为/var/www/app2
1. 基础路径映射配置
server {
listen 80;
server_name example.com;
root /var/www; # 父目录
# 应用 A:匹配 /app1 路径
location /app1 {
# 实际文件目录为 /var/www/app1
alias /var/www/app1; # 注意:这里用 alias 而非 root(关键区别)
index index.html;
# 解决 History 路由刷新 404
try_files $uri $uri/ /app1/index.html;
}
# 应用 B:匹配 /app2 路径
location /app2 {
alias /var/www/app2;
index index.html;
try_files $uri $uri/ /app2/index.html;
}
}
关键区别:alias
vs root
-
root /var/www
:请求/app1/static/css.css
会映射到/var/www/app1/static/css.css
(拼接完整路径)。 -
alias /var/www/app1
:请求/app1/static/css.css
会直接映射到/var/www/app1/static/css.css
(替换/app1
为实际目录),更适合子路径部署。
2. 需要解决的重写问题及方案
(1)前端资源引用路径错误
问题:应用内的静态资源(如 js
、css
、图片)若使用绝对路径(如 /static/js/main.js
),会被解析为 example.com/static/js/main.js
,而非 example.com/app1/static/js/main.js
,导致 404。
解决方案:
- 前端打包时配置 公共路径(publicPath):
- Vue 项目:在
vue.config.js
中设置publicPath: '/app1/'
- React 项目:在
package.json
中设置homepage: '/app1'
- Vue 项目:在
- 资源引用使用相对路径(如
./static/js/main.js
),避免绝对路径。
(2)接口请求路径前缀问题
问题:应用内的接口请求(如 /api/user
)会被发送到 example.com/api/user
,若需要根据子路径区分接口(如 example.com/app1/api/user
),需调整代理规则。
解决方案:
- 前端统一为接口添加路径前缀(如
axios.defaults.baseURL = '/app1/api'
)。 - Nginx 配置对应代理规则:
location /app1/api { # 移除 /app1 前缀后转发到后端 proxy_pass http://backend:3000/api; # 或 http://backend:3000/(根据后端路径调整) }
(3)路由跳转路径错误
问题:SPA 路由跳转(如从 /app1/home
跳转到 /app1/about
)若使用绝对路径,可能因框架路由配置未添加基础路径导致跳转错误。
解决方案:
- 前端路由配置基础路径:
- Vue Router:
base: '/app1/'
- React Router:
basename="/app1"
- Vue Router:
三、总结
-
多环境隔离:
- 推荐使用
include
指令拆分配置文件,实现模块化管理。 - 或通过虚拟主机(不同域名/端口)实现环境隔离,适合团队协作。
- 推荐使用
-
同域名不同路径映射:
- 使用
alias
指令正确映射子路径到实际文件目录。 - 解决资源引用问题:前端配置
publicPath
,使用相对路径。 - 解决接口和路由问题:统一添加路径前缀,配置对应 Nginx 代理和前端路由基础路径。
- 使用
通过以上配置,可以实现前端多环境的清晰隔离和同域名下多应用的无冲突部署。
1141. Nginx 如何配置支持前端大资源的 Range 分片请求?核心参数是什么?【热度: 146】【web 应用场景】
关键词:nginx 配置分片请求
Nginx 支持前端大资源(如视频、大型压缩包等)的 Range 分片请求,主要通过配置实现对 HTTP 范围请求的支持,允许客户端分段块下载资源,提升大文件传输效率。以下是具体配置方法和核心参数解析:
一、Range 分片请求的原理
HTTP 协议的 Range
请求头允许客户端只请求资源的一部分(如 Range: bytes=0-1023
表示请求前 1024 字节),服务器通过 Accept-Ranges
和 Content-Range
头响应支持状态和分片数据。
Nginx 默认已支持 Range 请求,但需确保配置正确以避免功能被禁用,尤其针对大文件场景需优化相关参数。
二、核心配置(支持 Range 请求)
1. 基础配置(启用 Range 支持)
server {
listen 80;
server_name example.com;
root /path/to/large-files; # 存放大资源的目录
# 关键:确保未禁用 Range 请求(默认启用,无需额外配置,但需避免以下错误)
# 错误示例:禁用 Range 的配置(生产环境需删除)
# proxy_set_header Range ""; # 禁止传递 Range 头
# add_header Accept-Ranges none; # 告知客户端不支持 Range
# 大文件传输优化(可选但推荐)
location / {
# 支持断点续传和分片请求(默认开启,显式声明更清晰)
add_header Accept-Ranges bytes;
# 读取文件的缓冲区大小(根据服务器内存调整)
client_body_buffer_size 10M;
# 发送文件的缓冲区大小(优化大文件传输效率)
sendfile on; # 启用零拷贝发送文件
tcp_nopush on; # 配合 sendfile 提高网络效率
tcp_nodelay off; # 减少小包发送,适合大文件
# 超时设置(避免大文件传输中断)
client_header_timeout 60s;
client_body_timeout 60s;
send_timeout 300s; # 发送超时延长至 5 分钟
}
}
2. 核心参数解析
-
Accept-Ranges: bytes
响应头,明确告知客户端服务器支持字节范围的分片请求(这是支持 Range 的核心标志)。Nginx 默认会自动添加该头,无需显式配置,但显式声明可增强配置可读性。 -
sendfile on
启用零拷贝(zero-copy)机制,让 Nginx 直接从磁盘读取文件并发送到网络,跳过用户态到内核态的数据拷贝,大幅提升大文件传输效率(对 Range 分片请求尤其重要)。 -
tcp_nopush on
与sendfile
配合使用,在发送文件时先积累一定数据量再一次性发送,减少网络包数量,适合大文件的连续分片传输。 -
proxy_set_header Range $http_range
(反向代理场景)
若大资源存储在后端服务(而非 Nginx 本地),需通过此配置将客户端的Range
请求头传递给后端,确保后端能正确处理分片请求:location /large-files { proxy_pass http://backend-server; proxy_set_header Range $http_range; # 传递 Range 头 proxy_set_header If-Range $http_if_range; # 传递 If-Range 头(验证资源是否修改) proxy_pass_request_headers on; # 确保所有请求头被传递 }
三、验证 Range 请求是否生效
可通过 curl
命令测试服务器是否支持分片请求:
# 测试请求前 1024 字节
curl -v -H "Range: bytes=0-1023" http://example.com/large-file.mp4
若响应中包含以下头信息,则表示配置生效:
HTTP/1.1 206 Partial Content # 206 状态码表示部分内容响应
Accept-Ranges: bytes
Content-Range: bytes 0-1023/10485760 # 表示返回 0-1023 字节,总大小 10485760 字节
四、注意事项
-
避免禁用 Range 的配置
确保配置中没有add_header Accept-Ranges none
或proxy_set_header Range ""
等禁用 Range 的指令,这些会导致客户端分片请求失败。 -
后端服务配合
若资源通过反向代理从后端服务获取,需确保后端服务本身支持 Range 请求(如 Node.js、Java 服务需实现对Range
头的处理),否则 Nginx 无法单独完成分片响应。 -
大文件存储优化
对于超大型文件(如 GB 级视频),建议结合open_file_cache
配置缓存文件描述符,减少频繁打开文件的开销:open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on;
总结
Nginx 支持 Range 分片请求的核心是:
- 确保默认的
Accept-Ranges: bytes
响应头有效(不被禁用)。 - 启用
sendfile
等传输优化参数提升大文件处理效率。 - 反向代理场景下需传递
Range
相关请求头给后端服务。
通过以上配置,前端可以实现大资源的断点续传、分片下载,显著提升用户体验。
1142. Nginx 如何按资源类型(如.js/.png)分发到不同服务器?配置策略是什么?【热度: 159】【web 应用场景】【出题公司: 阿里巴巴】
关键词:nginx 转发
Nginx 可以通过 location
指令匹配不同资源类型(如 .js
、.png
),并将请求分发到不同服务器,实现资源的分类部署和负载均衡。这种配置策略适合将静态资源(JS、图片)与动态资源(API)分离部署,提升整体服务性能。
一、核心配置策略:按文件后缀匹配并转发
通过 location
块的正则表达式匹配符(区分大小写)或 ~* 匹配符(不区分大小写),根据文件后缀名匹配不同资源类型,再通过 proxy_pass
转发到对应服务器。
1. 基础配置示例(分离 JS/CSS 与图片资源)
http {
# 定义后端服务器组(可配置负载均衡)
# JS/CSS 资源服务器组
upstream js_css_servers {
server 192.168.1.101:8080; # JS/CSS 服务器1
server 192.168.1.102:8080; # JS/CSS 服务器2(负载均衡)
}
# 图片资源服务器组
upstream image_servers {
server 192.168.1.201:8080; # 图片服务器1
server 192.168.1.202:8080; # 图片服务器2(负载均衡)
}
# 其他资源(如HTML、API)服务器
upstream default_server {
server 192.168.1.301:8080;
}
server {
listen 80;
server_name example.com;
# 1. 匹配 .js 和 .css 文件,转发到 JS/CSS 服务器组
location ~* \.(js|css)$ {
proxy_pass http://js_css_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 静态资源缓存优化(可选)
expires 1d; # 缓存 1 天
add_header Cache-Control "public, max-age=86400";
}
# 2. 匹配图片文件(.png/.jpg/.jpeg/.gif/.webp),转发到图片服务器组
location ~* \.(png|jpg|jpeg|gif|webp)$ {
proxy_pass http://image_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 图片缓存时间更长(可选)
expires 7d; # 缓存 7 天
add_header Cache-Control "public, max-age=604800";
}
# 3. 其他所有请求(如 HTML、API)转发到默认服务器
location / {
proxy_pass http://default_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
二、配置策略解析
1. 匹配规则说明
-
~* \.(js|css)$
:-
~*
表示不区分大小写匹配(如.JS
、.Css
也会被匹配)。 -
\.(js|css)$
是正则表达式,匹配以.js
或.css
结尾的请求。
-
-
优先级注意:
Nginx 的location
匹配有优先级,精确匹配(=
)> 前缀匹配(不含正则)> 正则匹配(~
/~*
)。
因此,按资源类型的正则匹配会优先于普通前缀匹配(如/static
),需确保规则无冲突。
2. 服务器组(upstream)配置
- 通过
upstream
定义同类资源的服务器集群,支持负载均衡策略(默认轮询):- 可添加
weight=2
调整权重(如server 192.168.1.101:8080 weight=2;
)。 - 可添加
backup
配置备用服务器(如server 192.168.1.103:8080 backup;
)。
- 可添加
3. 资源优化补充配置
-
缓存策略:静态资源(JS、图片)通常不频繁变动,通过
expires
和Cache-Control
头设置浏览器缓存,减少重复请求。 -
防盗链:图片等资源可添加防盗链配置,防止被其他网站盗用:
location ~* \.(png|jpg|jpeg|gif|webp)$ { # 仅允许 example.com 域名引用图片 valid_referers none blocked example.com *.example.com; if ($invalid_referer) { return 403; # 非法引用返回 403 } # ... 其他配置 }
三、扩展场景:按目录 + 资源类型组合匹配
若资源按目录分类(如 /static/js
、/static/img
),可结合目录和后缀匹配,进一步细化转发规则:
# 仅匹配 /static/js 目录下的 .js 文件
location ~* /static/js/.*\.js$ {
proxy_pass http://js_servers;
}
# 仅匹配 /static/img 目录下的图片文件
location ~* /static/img/.*\.(png|jpg)$ {
proxy_pass http://image_servers;
}
四、注意事项
-
正则表达式效率:
过多复杂的正则匹配会影响 Nginx 性能,建议资源类型规则尽量简洁(如合并同类后缀)。 -
后端资源路径一致性:
确保转发目标服务器的资源路径与请求路径一致。例如,请求example.com/static/a.js
被转发到js_css_servers
后,服务器需能在/static/a.js
路径找到资源。 -
HTTPS 场景适配:
若使用 HTTPS,配置逻辑不变,只需在server
块中添加 SSL 证书配置,转发目标可保持 HTTP(内部通信)或 HTTPS(跨公网)。
总结
按资源类型分发的核心策略是:
- 用
location ~* \.(后缀1|后缀2)$
匹配不同资源类型。 - 通过
upstream
定义对应资源的服务器集群,支持负载均衡。 - 结合缓存、防盗链等配置优化静态资源访问。
这种方案能实现资源的分类部署,减轻单服务器压力,同时针对不同资源类型(如图片、JS)进行专项优化,提升整体服务性能。
1143. Nginx 配置 gzip/brotli 压缩时需考虑哪些因素?为何不建议对所有前端资源开启压缩?【热度: 106】【web 应用场景】【出题公司: 阿里巴巴】
关键词:nginx 配置资源压缩
在 Nginx 中配置 gzip 或 brotli 压缩时,需综合考虑压缩效率、服务器性能开销、客户端兼容性等核心因素;而不建议对所有前端资源开启压缩,本质是避免“无效压缩”(压缩后体积无明显减小)和“反向损耗”(压缩耗时 > 传输耗时)。以下是具体分析:
一、配置 gzip/brotli 需考虑的核心因素
无论是 gzip 还是 brotli(压缩率通常优于 gzip,但需额外模块支持),配置时需围绕“收益最大化、损耗最小化”展开,核心考虑因素如下:
1. 资源类型适配:选择“高压缩收益”的资源
不同资源的压缩潜力差异极大,需优先对文本类资源开启压缩(压缩率高、收益显著),对二进制资源谨慎处理(压缩率低、甚至体积变大)。
资源类型 | 压缩收益 | 建议配置 | 原因 |
---|---|---|---|
HTML/CSS/JS | 极高 | 强制开启 | 文本内容重复度高,压缩率可达 60%-80%,传输体积大幅减小。 |
JSON/XML | 极高 | 强制开启 | 结构化文本,压缩率与 JS 接近,尤其适合 API 响应数据。 |
图片(PNG/JPG) | 极低 | 禁止开启 | 本身已是压缩格式(PNG 无损压缩、JPG 有损压缩),再压缩体积基本不变,反而增加耗时。 |
视频(MP4/WEBM) | 极低 | 禁止开启 | 视频编码已做深度压缩,gzip/brotli 无法进一步减小体积,纯浪费资源。 |
字体(WOFF2) | 中 | 可选开启 | WOFF2 本身已内置压缩(基于 brotli),再压缩收益有限;若使用旧字体格式(WOFF/TTF),可开启。 |
压缩包(ZIP/RAR) | 极低 | 禁止开启 | 压缩包本身是压缩格式,二次压缩可能导致体积轻微增大。 |
2. 压缩级别:平衡“压缩率”与“服务器耗时”
gzip 和 brotli 均支持多级别压缩(级别越高,压缩率越高,但消耗 CPU 资源越多、压缩耗时越长),需根据服务器性能和业务需求选择:
-
gzip 压缩级别(
gzip_comp_level 1-9
):- 级别 1-3:轻量压缩,CPU 消耗低,耗时短,适合高并发场景(如秒杀、峰值流量),压缩率约 40%-50%;
- 级别 4-6:平衡压缩率与性能,默认推荐级别(Nginx 默认是 1,需手动调至 4-6),压缩率约 50%-70%;
- 级别 7-9:高强度压缩,CPU 消耗高,耗时久,仅适合低并发、对带宽敏感的场景(如静态资源 CDN 后台)。
-
brotli 压缩级别(
brotli_comp_level 1-11
):
比 gzip 多 2 个级别,压缩率更高(同级别下比 gzip 高 10%-20%),但 CPU 消耗也更高。推荐级别 4-8,避免使用 9-11(耗时显著增加,收益边际递减)。
3. 客户端兼容性:避免“压缩后客户端无法解压”
压缩生效的前提是客户端支持对应压缩算法(通过 HTTP 请求头 Accept-Encoding: gzip, br
告知服务器),需避免对不支持的客户端发送压缩数据:
- gzip 兼容性:几乎所有现代浏览器(IE6+)、客户端均支持,兼容性无压力。
-
brotli 兼容性:支持 95% 以上现代浏览器(Chrome 49+、Firefox 44+、Edge 15+),但需注意:
- 仅支持 HTTPS 环境(部分浏览器限制 HTTP 下不使用 brotli);
- 需 Nginx 额外安装
ngx_brotli
模块(默认不内置,需编译时添加或通过动态模块加载)。
配置时需通过 gzip_disable
/brotli_disable
排除不支持的客户端,例如:
# gzip:排除 IE6 及以下不支持的客户端
gzip_disable "MSIE [1-6]\.";
# brotli:仅对支持的客户端生效(依赖 Accept-Encoding 头)
brotli on;
brotli_types text/html text/css application/javascript application/json;
4. 压缩阈值:避免“小文件压缩反而耗时”
对极小文件(如 < 1KB 的 CSS/JS 片段)开启压缩,可能出现“压缩耗时 > 传输耗时”的反向损耗——因为压缩需要 CPU 计算,而小文件即使不压缩,传输耗时也极短。
需通过 gzip_min_length
/brotli_min_length
设置“压缩阈值”,仅对超过阈值的文件开启压缩(Nginx 默认 gzip_min_length 20
,即 20 字节,建议调整为 1KB 以上):
# 仅对 > 1KB 的文件开启压缩(单位:字节)
gzip_min_length 1024;
brotli_min_length 1024;
5. 缓存与预压缩:减少“重复压缩”损耗
Nginx 默认“实时压缩”(每次请求都重新压缩资源),若资源长期不变(如静态 JS/CSS),会导致重复的 CPU 消耗。需通过以下方式优化:
-
开启压缩缓存:通过
gzip_buffers
配置内存缓存,减少重复压缩(Nginx 默认开启,建议调整缓存块大小适配资源):# gzip 缓存:4 个 16KB 块(总 64KB),适配中小型文本资源 gzip_buffers 4 16k;
-
预压缩静态资源:提前通过工具(如
gzip
命令、brotli
命令)生成压缩后的资源文件(如app.js.gz
、app.js.br
),Nginx 直接返回预压缩文件,避免实时压缩:# 优先返回预压缩的 .gz 文件(若存在) gzip_static on; # 优先返回预压缩的 .br 文件(若存在,需 brotli 模块支持) brotli_static on;
6. 服务器性能:避免“压缩耗尽 CPU 资源”
压缩(尤其是高级别压缩)会消耗 CPU 资源,若服务器 CPU 核心数少(如 1-2 核)或并发量极高(如每秒万级请求),过度压缩可能导致 CPU 使用率飙升,影响其他服务(如动态请求处理)。
需结合服务器配置调整:
- 低配置服务器(1-2 核):使用 gzip 级别 1-3,关闭 brotli;
- 中高配置服务器(4 核以上):使用 gzip 级别 4-6 或 brotli 级别 4-8;
- 可通过
gzip_threads
(仅部分 Nginx 版本支持)开启多线程压缩,分摊 CPU 压力:# 开启 2 个线程处理 gzip 压缩 gzip_threads 2;
二、为何不建议对所有前端资源开启压缩?
核心原因是“部分资源压缩无收益,反而增加损耗”,具体可归纳为 3 类:
1. 压缩收益为负:体积不变或增大
- 已压缩的二进制资源(如 PNG/JPG/MP4/ZIP):本身已通过专业算法压缩(如 JPG 的 DCT 变换、MP4 的 H.264 编码),gzip/brotli 无法进一步减小体积,甚至因“压缩头额外开销”导致体积轻微增大(如 10MB 的 MP4 压缩后可能变成 10.01MB)。
2. 性能损耗 > 传输收益
- 极小文件(如 < 1KB 的 CSS 片段、小图标 base64 字符串):压缩耗时(即使 1ms)可能超过“压缩后减少的传输时间”(假设带宽 100Mbps,1KB 传输时间仅 0.08ms),反而拖慢整体响应速度。
3. 客户端兼容性风险
- 若对不支持 brotli 的旧客户端(如 IE11)发送 brotli 压缩数据,客户端无法解压,会直接返回“空白页面”或“乱码”;
- 虽可通过
Accept-Encoding
头判断,但配置不当(如遗漏brotli_disable
)仍可能出现兼容性问题,而“不压缩所有资源”是更稳妥的规避方式。
三、推荐的 gzip + brotli 配置示例
结合上述因素,以下是兼顾“性能、兼容性、收益”的配置(需确保 Nginx 已安装 brotli 模块):
http {
# -------------------------- gzip 配置 --------------------------
gzip on; # 开启 gzip
gzip_comp_level 5; # 平衡级别(压缩率 ~60%,CPU 消耗适中)
gzip_min_length 1024; # 仅压缩 >1KB 的文件
gzip_buffers 4 16k; # 内存缓存块
gzip_types
text/html text/css application/javascript
application/json application/xml
text/plain text/javascript; # 仅对文本类资源压缩
gzip_disable "MSIE [1-6]\."; # 排除 IE6 及以下
gzip_static on; # 优先使用预压缩的 .gz 文件
gzip_vary on; # 向客户端返回 Vary: Accept-Encoding 头(利于 CDN 缓存)
# -------------------------- brotli 配置 --------------------------
brotli on; # 开启 brotli
brotli_comp_level 6; # 平衡级别(压缩率 ~70%,比 gzip 高 10%)
brotli_min_length 1024; # 同 gzip 阈值
brotli_types
text/html text/css application/javascript
application/json application/xml
text/plain text/javascript; # 仅对文本类资源压缩
brotli_disable "MSIE [1-6]\.|Firefox/[1-43]\."; # 排除不支持的旧浏览器
brotli_static on; # 优先使用预压缩的 .br 文件
brotli_vary on; # 同 gzip_vary
}
总结
配置 Nginx 压缩的核心逻辑是“针对性优化”:
- 只对“文本类资源”(HTML/CSS/JS/JSON)开启压缩,对“二进制资源”(图片/视频/压缩包)坚决关闭;
- 选择“平衡的压缩级别”,避免过度消耗 CPU;
- 通过“预压缩”和“缓存”减少实时压缩损耗;
- 兼容旧客户端,避免因压缩导致的访问异常。
这种策略既能最大化压缩带来的“带宽节省、加载加速”收益,又能最小化服务器性能损耗和兼容性风险。
1145. 微前端通过 Nginx 实现主 / 子应用路由分发,如何配置 location 和 try_files?需处理哪些资源路径问题?【热度: 120】【web 应用场景】
微前端通过 Nginx 实现主/子应用路由分发时,核心是通过 location
匹配不同应用的路由路径,并结合 try_files
处理 SPA 路由刷新 404 问题。同时需解决子应用资源路径、主/子应用路由冲突等关键问题。以下是具体实现方案:
一、基础场景:主应用与子应用通过路径前缀区分
假设:
- 主应用路由:
https://example.com/
(根路径) - 子应用 A 路由:
https://example.com/app1/
(前缀/app1
) - 子应用 B 路由:
https://example.com/app2/
(前缀/app2
)
1. 目录结构(前端资源存放)
/var/www/
├── main-app/ # 主应用打包文件
│ ├── index.html
│ ├── static/
│ └── ...
├── app1/ # 子应用 A 打包文件
│ ├── index.html
│ ├── static/
│ └── ...
└── app2/ # 子应用 B 打包文件
├── index.html
└── ...
2. Nginx 核心配置(location + try_files)
server {
listen 80;
server_name example.com;
root /var/www; # 父目录(包含所有应用)
# 1. 主应用路由(根路径 /)
location / {
# 主应用实际目录为 /var/www/main-app
alias /var/www/main-app/;
index index.html;
# 解决主应用 History 路由刷新 404
# 逻辑:优先匹配物理文件,匹配不到则返回主应用 index.html
try_files $uri $uri/ /main-app/index.html;
}
# 2. 子应用 A 路由(/app1 前缀)
location /app1 {
# 子应用 A 实际目录为 /var/www/app1
alias /var/www/app1/;
index index.html;
# 解决子应用 A History 路由刷新 404
# 注意:try_files 最后需指向子应用自己的 index.html
try_files $uri $uri/ /app1/index.html;
}
# 3. 子应用 B 路由(/app2 前缀)
location /app2 {
alias /var/www/app2/;
index index.html;
try_files $uri $uri/ /app2/index.html;
}
}
二、关键配置解析
1. alias
与 root
的选择
-
必须使用
alias
:子应用路径(如/app1
)与实际目录(/var/www/app1
)是“映射关系”,alias
会将/app1
直接替换为实际目录(如请求/app1/static.js
映射到/var/www/app1/static.js
)。 - 若误用
root
:root /var/www
会在请求路径后拼接目录(/app1/static.js
会映射到/var/www/app1/static.js
,看似可行,但子应用内路由跳转可能出现异常)。
2. try_files
的路径规则
- 主应用:
try_files $uri $uri/ /main-app/index.html
最后一个参数必须是主应用index.html
的绝对路径(相对于 Nginx 根目录),确保主应用路由(如/home
)刷新时返回主应用入口。 - 子应用:
try_files $uri $uri/ /app1/index.html
最后一个参数必须是子应用自己的index.html
(如/app1/index.html
),否则子应用路由(如/app1/detail
)刷新会返回主应用入口,导致路由错乱。
三、需处理的资源路径问题
微前端路由分发的核心坑点是资源路径引用错误,需从 Nginx 配置和前端打包两方面协同解决:
1. 子应用静态资源路径错误(404)
问题:子应用打包时若使用绝对路径(如 src="/static/js/app1.js"
),会被解析为 https://example.com/static/js/app1.js
,但实际路径应为 https://example.com/app1/static/js/app1.js
,导致 404。
解决方案:
-
前端打包配置:子应用需设置
publicPath
为自身路径前缀(如/app1/
):- Vue 项目:
vue.config.js
中publicPath: '/app1/'
- React 项目:
package.json
中homepage: '/app1'
或webpack.config.js
中output.publicPath: '/app1/'
- Vue 项目:
-
效果:资源引用会自动添加
/app1
前缀(如src="/app1/static/js/app1.js"
),匹配 Nginx 配置的alias
路径。
2. 主/子应用路由冲突
问题:若主应用存在 /app1
路由,会与子应用的 /app1
路径冲突,导致主应用路由被 Nginx 拦截并转发到子应用。
解决方案:
-
路由命名规范:子应用路径前缀需全局唯一(如
/micro-app1
、/micro-app2
),避免与主应用路由重名。 -
Nginx 优先级控制:若必须使用相同前缀,可通过
location
精确匹配优先处理主应用路由:# 主应用的 /app1 路由(精确匹配,优先级高于子应用的 /app1 前缀匹配) location = /app1 { alias /var/www/main-app/; try_files $uri $uri/ /main-app/index.html; } # 子应用 /app1 前缀路由(优先级低) location /app1/ { alias /var/www/app1/; try_files $uri $uri/ /app1/index.html; }
3. 子应用接口请求路径错误
问题:子应用接口请求(如 /api/data
)会被发送到 https://example.com/api/data
,若需区分子应用接口(如 https://example.com/app1/api/data
),需调整代理规则。
解决方案:
-
前端统一前缀:子应用接口请求添加自身路径前缀(如
axios.defaults.baseURL = '/app1/api'
)。 -
Nginx 代理转发:
# 子应用 A 的接口代理 location /app1/api { # 移除 /app1 前缀后转发到后端(如后端接口实际路径为 /api) proxy_pass http://backend-server/api; proxy_set_header Host $host; }
4. 子应用懒加载路由资源 404
问题:子应用使用路由懒加载时(如 Vue/React 的 import('./page.vue')
),打包后的 chunk 文件路径可能未包含子应用前缀,导致加载失败。
解决方案:
- 确保懒加载的 chunk 路径也使用
publicPath
配置的前缀,现代打包工具(Webpack 5+、Vite)会自动处理,只需正确设置publicPath
即可。
四、复杂场景:子应用嵌套或动态路径
若子应用包含动态路由(如 /app1/user/:id
)或嵌套路由(如 /app1/dashboard/settings
),Nginx 配置无需额外调整,因为 location /app1
会匹配所有以 /app1
开头的路径,try_files
会统一指向子应用 index.html
,路由解析由子应用前端框架完成。
五、总结
微前端 Nginx 路由分发的核心配置要点:
- 用
location /app1
匹配子应用路径,alias
指向实际目录。 - 用
try_files $uri $uri/ /app1/index.html
解决子应用 History 路由刷新 404。 - 必须处理的资源问题:
- 子应用打包设置
publicPath
为路径前缀(如/app1/
)。 - 避免主/子应用路由重名,接口请求添加子应用前缀。
- 子应用打包设置
通过以上配置,可实现主/子应用路由的无冲突分发,确保静态资源和路由正常访问。
1146. Nginx 配置 HTTPS 需哪些核心项(协议、加密套件)?如何强制 HTTP 跳转 HTTPS?【热度: 182】【web 应用场景】
关键词:nginx 配置 https
Nginx 配置 HTTPS 需重点关注协议版本、加密套件、证书配置等核心项,同时需正确设置 HTTP 到 HTTPS 的强制跳转。以下是详细配置方案:
一、HTTPS 核心配置项(协议、加密套件等)
HTTPS 配置的核心目标是确保安全性(禁用不安全协议和加密套件)和兼容性(支持主流浏览器),关键配置项缺一不可:
1. 证书与私钥配置(必备)
需指定 SSL 证书(公钥)和私钥文件路径,证书需由可信 CA 机构签发(如 Let's Encrypt、阿里云等):
server {
listen 443 ssl; # 监听 443 端口并启用 SSL
server_name example.com; # 证书绑定的域名
# 证书文件路径(PEM 格式)
ssl_certificate /path/to/fullchain.pem; # 包含服务器证书和中间证书
ssl_certificate_key /path/to/privkey.pem; # 服务器私钥
}
2. 协议版本(禁用不安全协议)
需明确启用现代安全协议,禁用已被破解或不安全的旧协议(如 SSLv2、SSLv3、TLSv1.0、TLSv1.1):
# 仅启用 TLSv1.2 和 TLSv1.3(目前最安全的协议版本)
ssl_protocols TLSv1.2 TLSv1.3;
-
为何禁用旧协议:
TLSv1.0/1.1 存在安全漏洞(如 BEAST 攻击),且不支持现代加密套件;SSL 协议已完全过时,必须禁用。
3. 加密套件(优先选择强加密算法)
加密套件决定数据传输的加密方式,需优先选择支持前向 secrecy(完美前向保密) 和AES-GCM 等强加密算法的套件:
# 现代浏览器兼容的强加密套件(TLSv1.2+)
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# 优先使用服务器端的加密套件选择(增强安全性)
ssl_prefer_server_ciphers on;
-
核心原则:
避免使用 RSA 密钥交换(无 Forward Secrecy)和 CBC 模式加密(存在漏洞),优先 ECDHE 密钥交换 + GCM 模式。
4. 性能与安全性优化项
# SSL 会话缓存(减少握手耗时,提升性能)
ssl_session_cache shared:SSL:10m; # 共享缓存,容量 10MB(约 40000 个会话)
ssl_session_timeout 1d; # 会话超时时间(1天)
# 启用 HSTS(强制客户端后续使用 HTTPS 访问,防降级攻击)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# 禁用 SSL 压缩(防止 CRIME 攻击)
ssl_compression off;
# 启用 OCSP Stapling(减少证书验证步骤,提升加载速度)
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/fullchain.pem; # 与 ssl_certificate 一致即可
resolver 8.8.8.8 114.114.114.114 valid=300s; # DNS 解析器(用于验证 OCSP 响应)
二、强制 HTTP 跳转 HTTPS 的配置方法
需将所有 HTTP(80 端口)请求强制重定向到 HTTPS(443 端口),确保用户始终使用加密连接。推荐两种可靠方案:
1. 方案一:通过 301 永久重定向(推荐)
在 80 端口的 server
块中直接返回 301 重定向,适用于大多数场景:
# HTTP 服务器(80端口):仅用于跳转 HTTPS
server {
listen 80;
server_name example.com; # 需与 HTTPS 服务器的域名一致
# 永久重定向到 HTTPS
return 301 https://$host$request_uri;
}
- 优势:简单高效,搜索引擎会记住重定向,将权重转移到 HTTPS 域名。
2. 方案二:通过 rewrite 指令(灵活适配复杂场景)
若需对特定路径做特殊处理(如临时不跳转某些路径),可使用 rewrite
:
server {
listen 80;
server_name example.com;
# 对 /api/temp 路径临时不跳转(示例)
location /api/temp {
# 保持 HTTP 访问(仅临时使用,不推荐长期保留)
proxy_pass http://backend;
}
# 其他所有路径跳转 HTTPS
location / {
rewrite ^(.*)$ https://$host$1 permanent; # permanent 等价于 301
}
}
三、完整 HTTPS 配置示例
# HTTP 服务器:强制跳转 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
# HTTPS 服务器:核心配置
server {
listen 443 ssl;
server_name example.com;
# 证书配置
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# 协议与加密套件
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
# 性能与安全优化
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_compression off;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/fullchain.pem;
resolver 8.8.8.8 114.114.114.114 valid=300s;
# 前端资源配置(如 SPA 路由、缓存等)
root /path/to/frontend;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
四、关键注意事项
-
证书路径正确性:
确保ssl_certificate
和ssl_certificate_key
指向的文件存在且权限正确(Nginx 进程需可读,建议权限 600)。 -
HSTS 配置风险:
Strict-Transport-Security
头一旦设置,客户端会严格遵守(即使后续关闭 HTTPS 也会强制使用),需确保 HTTPS 服务长期稳定后再添加preload
选项。 -
兼容性平衡:
若需支持非常旧的浏览器(如 IE 10),可临时启用 TLSv1.1,但需知晓安全风险;现代网站建议仅保留 TLSv1.2+。 -
配置验证:
修改配置后需执行nginx -t
检查语法,通过nginx -s reload
生效;可使用 SSL Labs 工具 检测配置安全性(目标评分 A+)。
总结
HTTPS 核心配置包括:
- 证书与私钥(基础)、TLSv1.2+ 协议(安全)、强加密套件(防破解);
- 强制跳转通过 301 重定向实现,确保所有 HTTP 请求转向 HTTPS。
合理配置可在安全性、兼容性和性能之间取得平衡,是现代网站的必备实践。
1147. 前端静态资源加载超时,Nginx 可通过哪些配置优化?【热度: 190】【web 应用场景】【出题公司: 阿里巴巴】
关键词:nginx 加载超时优化
前端静态资源(如 JS、CSS、图片、视频等)加载超时,通常与网络传输效率、服务器响应速度或资源处理策略相关。Nginx 可通过针对性配置优化传输效率、延长超时阈值、减少阻塞风险,从而解决超时问题。以下是具体优化方案:
一、延长关键超时时间(避免传输中断)
针对大资源(如视频、大型 JS 包)或弱网络环境,默认超时时间可能不足,需调整以下参数:
server {
# 1. 客户端与服务器建立连接的超时(握手阶段)
client_header_timeout 120s; # 等待客户端发送请求头的超时(默认 60s,延长至 2 分钟)
client_body_timeout 120s; # 等待客户端发送请求体的超时(默认 60s)
# 2. 服务器向客户端发送响应的超时(传输阶段,核心!)
send_timeout 300s; # 大文件传输时,服务器发送数据的超时(默认 60s,延长至 5 分钟)
# 3. 长连接保持时间(复用连接,减少重复握手开销)
keepalive_timeout 120s; # 连接空闲后保持的时间(默认 75s,延长至 2 分钟)
keepalive_requests 200; # 单个长连接可处理的请求数(默认 100,提高至 200)
}
关键逻辑:send_timeout
是防止大资源传输中断的核心参数(如 100MB 的视频文件,弱网环境可能需要几分钟传输),需根据资源最大体积和目标用户网络环境调整。
二、优化资源传输效率(减少传输耗时)
通过零拷贝、数据合并、压缩等技术,减少资源在服务器与客户端之间的传输时间:
1. 启用零拷贝与 TCP 优化
location ~* \.(js|css|png|jpg|jpeg|webp|mp4)$ {
# 零拷贝:直接从磁盘读取文件发送到网络,跳过用户态-内核态数据拷贝(核心优化!)
sendfile on;
# 配合 sendfile 使用,积累数据后一次性发送,减少网络包数量(提升大文件传输效率)
tcp_nopush on;
# 禁用 Nagle 算法(减少小数据包延迟,适合动态内容,但大文件建议关闭)
tcp_nodelay off;
}
2. 启用压缩(减小传输体积)
对文本类资源(JS/CSS/HTML)启用 gzip 或 brotli 压缩,对图片等二进制资源确保已预压缩(如 WebP 格式):
# 全局压缩配置
gzip on;
gzip_comp_level 5; # 压缩级别 1-9(5 为平衡值)
gzip_min_length 1024; # 仅压缩 >1KB 的文件(小文件压缩收益低)
gzip_types
text/html text/css application/javascript
application/json image/svg+xml; # 仅压缩文本类资源
# 若 Nginx 安装了 brotli 模块(压缩率高于 gzip)
brotli on;
brotli_comp_level 6;
brotli_types text/css application/javascript;
3. 预压缩静态资源(避免实时压缩耗时)
提前对静态资源进行压缩(如 app.js
→ app.js.gz
),Nginx 直接返回预压缩文件,减少实时压缩的 CPU 消耗和延迟:
location ~* \.(js|css)$ {
gzip_static on; # 优先返回 .gz 预压缩文件(需手动生成或通过打包工具生成)
brotli_static on; # 优先返回 .br 预压缩文件
}
三、优化文件读取效率(减少服务器内部延迟)
静态资源加载超时可能是服务器磁盘 I/O 慢或文件打开频繁导致,可通过缓存文件描述符优化:
# 缓存打开的文件描述符(减少重复打开文件的磁盘 I/O 耗时)
open_file_cache max=10000 inactive=30s; # 最多缓存 10000 个文件,30s 未访问则移除
open_file_cache_valid 60s; # 每 60s 验证一次缓存有效性
open_file_cache_min_uses 2; # 文件被访问至少 2 次才加入缓存
open_file_cache_errors on; # 缓存"文件不存在"的错误(避免重复检查)
效果:频繁访问的静态资源(如首页 JS/CSS)会被缓存描述符,后续请求无需再次读取磁盘,响应速度提升 50%+。
四、限制并发与请求大小(避免服务器过载)
服务器资源耗尽(CPU/内存/磁盘 I/O 满)会导致响应延迟,需通过配置限制并发压力:
1. 限制单个请求体大小
防止超大文件请求阻塞服务器(如恶意上传 1GB 无效文件):
# 全局限制:单个请求体最大 100MB(根据业务调整,如图片站可设 50MB)
client_max_body_size 100m;
# 针对视频等超大资源单独限制
location /videos {
client_max_body_size 500m; # 视频文件最大 500MB
}
2. 调整 worker 进程与连接数
充分利用服务器 CPU 资源,提升并发处理能力:
# 在 nginx.conf 全局配置中
worker_processes auto; # 自动设置为 CPU 核心数(如 4 核服务器则启动 4 个进程)
worker_connections 10240; # 每个 worker 最大连接数(默认 1024,提高至 10240)
multi_accept on; # 允许每个 worker 同时接受多个新连接
五、CDN 与资源分片配合(彻底解决跨地域超时)
若用户分布在不同地域,仅靠源站优化效果有限,需结合:
-
静态资源托管到 CDN:
将 JS/CSS/图片等静态资源上传至 CDN(如 Cloudflare、阿里云 CDN),CDN 节点就近分发,减少跨地域传输延迟。
Nginx 需配置允许 CDN 缓存:location ~* \.(js|css|png)$ { add_header Cache-Control "public, max-age=31536000"; # 允许 CDN 长期缓存 add_header Access-Control-Allow-Origin *; # 解决 CDN 跨域问题 }
-
大文件分片传输:
对视频等超大型文件(>100MB),前端通过 Range 请求分片下载(如每次请求 10MB),Nginx 需支持 Range 分片(默认支持,无需额外配置):location /videos { add_header Accept-Ranges bytes; # 显式声明支持分片(默认已开启) }
六、完整优化配置示例
# nginx.conf 全局配置
worker_processes auto;
worker_connections 10240;
multi_accept on;
http {
# 压缩配置
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/html text/css application/javascript;
gzip_static on;
# 文件描述符缓存
open_file_cache max=10000 inactive=30s;
open_file_cache_valid 60s;
open_file_cache_min_uses 2;
server {
listen 80;
server_name example.com;
# 超时配置
client_header_timeout 120s;
client_body_timeout 120s;
send_timeout 300s;
keepalive_timeout 120s;
keepalive_requests 200;
# 请求体大小限制
client_max_body_size 100m;
# 静态资源优化
location ~* \.(js|css|png|jpg|jpeg|webp|mp4)$ {
root /path/to/frontend;
sendfile on;
tcp_nopush on;
tcp_nodelay off;
expires 30d; # 浏览器缓存,减少重复请求
}
# 视频等大资源单独配置
location /videos {
client_max_body_size 500m;
add_header Accept-Ranges bytes;
}
}
}
总结
Nginx 优化静态资源加载超时的核心思路是:
-
延长传输超时(
send_timeout
),适应大资源和弱网络; - 提升传输效率(零拷贝、压缩、预压缩),减少传输时间;
- 优化服务器性能(文件缓存、并发调整),减少内部延迟;
- 结合 CDN 与分片,解决跨地域传输问题。
通过多层优化,可显著降低静态资源加载超时概率,提升前端页面加载体验。
1148. Nginx 如何为不同前端资源配置缓存策略?如何强制刷新特定资源?【热度: 110】【web 应用场景】
关键词:nginx 加载特定资源
Nginx 为不同前端资源配置缓存策略的核心是根据资源特性(是否常变、是否带版本标识)差异化设置缓存规则,同时通过特定机制实现特定资源的强制刷新。以下是详细方案:
一、按资源类型配置差异化缓存策略
前端资源可分为静态资源(JS、CSS、图片等)和入口文件(如 index.html
),需根据其更新频率和版本管理方式设置不同缓存策略:
1. 带哈希/版本号的静态资源(永久强缓存)
特征:文件名含唯一哈希(如 app.8f3b.js
)或版本号(如 v2/style.css
),内容变化时文件名必变。
策略:设置长期强缓存,减少重复请求。
# 匹配带哈希的 JS/CSS/图片(假设哈希为 8-16 位字符)
location ~* \.\w{8,16}\.(js|css|png|jpg|jpeg|webp|svg)$ {
# 缓存 1 年(31536000 秒)
expires 365d;
# 强缓存标识:浏览器直接使用本地缓存,不发送请求
add_header Cache-Control "public, max-age=31536000, immutable";
}
-
关键参数:
immutable
(H5 新特性)告知浏览器资源不会变化,避免发送无效的条件请求(如If-Modified-Since
)。
2. 无哈希的静态资源(短期强缓存 + 协商缓存)
特征:文件名固定(如 favicon.ico
、common.js
),可能不定期更新但无版本标识。
策略:短期强缓存减少请求,过期后通过协商缓存验证是否更新。
# 匹配无哈希的图片、字体等
location ~* \.(png|jpg|jpeg|ico|woff2?)$ {
# 短期强缓存 7 天
expires 7d;
# 过期后必须验证是否更新
add_header Cache-Control "public, max-age=604800, must-revalidate";
}
3. 入口文件与动态页面(协商缓存)
特征:如 index.html
、page.html
,作为路由入口或动态内容载体,需确保用户获取最新版本。
策略:禁用强缓存,每次请求通过协商缓存验证。
# 入口文件(如 index.html)
location = /index.html {
# 禁用强缓存(立即过期)
expires -1;
# 协商缓存:必须向服务器验证
add_header Cache-Control "no-cache, must-revalidate";
}
# 其他 HTML 页面
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
}
-
协商缓存原理:Nginx 自动返回
Last-Modified
(文件修改时间),浏览器下次请求携带If-Modified-Since
,服务器比对后返回304
(未修改)或200
(新内容)。
4. API 接口与动态数据(无缓存或短时缓存)
特征:如 /api/user
,返回动态数据,需实时性。
策略:禁用缓存或设置极短缓存时间。
# API 接口
location /api {
# 完全禁用缓存
add_header Cache-Control "no-store, no-cache, must-revalidate";
expires -1;
# 转发到后端服务
proxy_pass http://backend;
}
二、强制刷新特定资源的方法
当资源更新但因缓存未生效时,需强制用户获取最新版本,核心思路是破坏缓存标识或主动清理缓存:
1. 前端主动更新资源标识(推荐)
利用“哈希/版本号与内容绑定”的特性,资源更新时修改文件名,浏览器会视为新资源自动请求:
- 例:
app.8f3b.js
→ 更新后变为app.9c4d.js
,无需 Nginx 配置,彻底避免缓存问题。
2. 通过 URL 参数强制刷新(临时方案)
对无哈希的资源,可在请求 URL 后添加随机参数(如 ?v=2
),使浏览器认为是新资源:
- 例:
common.js
→common.js?v=2
- Nginx 无需额外配置,但需前端手动更新参数,适合临时紧急更新。
3. 清理 CDN 缓存(若使用 CDN)
若资源通过 CDN 分发,需在 CDN 控制台手动清理特定资源缓存:
- 例:阿里云 CDN 支持按路径(如
/*/*.js
)或具体 URL 清理缓存,生效后用户请求会回源获取最新资源。
4. 动态修改资源的 Last-Modified
(不推荐)
通过 Nginx 指令强制修改资源的 Last-Modified
头,触发协商缓存更新:
# 强制刷新某个资源(如 common.js)
location = /static/js/common.js {
# 手动设置一个较新的修改时间(比实际文件新)
add_header Last-Modified "Wed, 20 Sep 2025 08:00:00 GMT";
# 协商缓存配置
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
}
- 缺点:需手动修改 Nginx 配置并 reload,仅适合紧急情况,不建议长期使用。
三、完整缓存配置示例
server {
listen 80;
server_name example.com;
root /path/to/frontend;
# 1. 带哈希的静态资源(永久缓存)
location ~* \.\w{8,16}\.(js|css|png|jpg|jpeg|webp|svg)$ {
expires 365d;
add_header Cache-Control "public, max-age=31536000, immutable";
}
# 2. 无哈希的静态资源(短期+协商)
location ~* \.(png|jpg|jpeg|ico|woff2?)$ {
expires 7d;
add_header Cache-Control "public, max-age=604800, must-revalidate";
}
# 3. 入口文件与 HTML(协商缓存)
location = /index.html {
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
}
# 4. API 接口(无缓存)
location /api {
add_header Cache-Control "no-store, no-cache";
expires -1;
proxy_pass http://backend;
}
# SPA 路由支持(配合 History 模式)
location / {
try_files $uri $uri/ /index.html;
}
}
四、关键注意事项
- 缓存与版本管理协同:前端打包工具(Webpack/Vite)需确保“内容变则哈希变”,与 Nginx 强缓存配合,这是最可靠的刷新方式。
-
避免缓存
index.html
:入口文件必须用协商缓存,否则用户可能无法获取新的哈希资源列表。 -
HTTPS 环境下的缓存:若启用 HTTPS,需确保
Cache-Control
头正确传递(Nginx 默认不拦截),避免 CDN 或代理服务器篡改缓存策略。
总结
- 差异化缓存:带哈希资源用永久强缓存,无哈希资源用短期+协商缓存,入口文件和 API 禁用强缓存。
- 强制刷新:优先通过修改资源哈希/版本号实现,临时场景可用 URL 参数,CDN 资源需手动清理 CDN 缓存。
这种策略既能最大化利用缓存提升性能,又能确保资源更新及时生效。