登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
23
Star
192
Fork
47
yanleweb
/
interview-question
代码
Issues
1091
Pull Requests
0
Wiki
统计
流水线
服务
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
如何通过 Nginx 配置前端静态资源的 “hash 资源永久缓存 + 非 hash 资源协商缓存”?【热度: 75】
待办的
#ICWQRJ
yanleweb
拥有者
创建于
2025-09-07 14:08
**关键词**:nginx 资源缓存 要实现前端前端静态资源的“hash 资源永久缓存 + 非 hash 资源协商缓存”,需结合 Nginx 的缓存头配置,针对不同类型资源设计差异化策略。核心思路是:**对带 hash 的指纹文件(如`app.8f3b.js`)设置长期强缓存,对无 hash 的文件(如`index.html`)使用协商缓存**,既以下是具体实现方案: ### 一、两种缓存策略的适用场景 | 资源类型 | 特征 | 缓存策略 | 目的 | | -------------- | ------------------------------------------------------------- | ---------- | -------------------------------------- | | 带 hash 的资源 | 文件名含唯一 hash(如`style.1a2b.css`),内容变化则 hash 变化 | 永久强缓存 | 一次缓存后不再请求,减少重复下载 | | 非 hash 的资源 | 文件名固定(如`index.html`、`favicon.ico`),内容可能动态更新 | 协商缓存 | 每次请求验证是否更新,确保获取最新内容 | ### 二、核心配置方案 通过`location`匹配不同资源类型,分别设置缓存头: ```nginx 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`:过期后必须向服务器验证是否更新。 ### 四、与前端打包的配合要点 1. **确保 hash 生成规则可靠**: 前端打包时,需保证“内容不变则 hash 不变,内容变化则 hash 必变”。例如: - Webpack:`contenthash`(基于文件内容生成 hash)。 - Vite:默认对静态资源生成 contenthash。 2. **避免 hash 资源依赖非 hash 资源**: 确保带 hash 的 JS/CSS 不引用无 hash 的资源(如`background: url(/img/bg.png)`),否则 bg.png 更新后,引用它的 CSS 因 hash 未变而无法更新。 解决方案:让被引用资源也带上 hash(如`bg.a1b2c3.png`)。 3. **index.html 必须无 hash**: 作为入口文件,`index.html`需通过协商缓存确保用户每次获取最新版本,从而加载新的 hash 资源。 ### 五、验证缓存是否生效 1. **强缓存验证**: 访问带 hash 的资源(如`app.8f3b.js`),在浏览器 Network 面板中查看: - 状态码为`200 OK (from disk cache)`或`200 OK (from memory cache)`。 - Response Headers 包含`Cache-Control: public, max-age=31536000, immutable`。 2. **协商缓存验证**: 访问`index.html`,刷新页面: - 第一次请求:状态码`200 OK`,Response Headers 有`Last-Modified`。 - 第二次请求:Request Headers 有`If-Modified-Since`,若未修改,状态码`304 Not Modified`。 ### 总结 通过 Nginx 实现“hash 资源永久缓存 + 非 hash 资源协商缓存”的核心是: 1. 利用 hash 文件名的唯一性,对静态资源设置长期强缓存,最大化减少重复请求。 2. 对入口文件等无 hash 资源启用协商缓存,确保内容更新时能被及时获取。 3. 前端打包与 Nginx 配置协同,保证 hash 机制可靠,避免缓存不一致问题。 这种策略既能大幅提升页面加载速度,又能确保资源更新的即时性,是前端性能优化的关键实践。
**关键词**:nginx 资源缓存 要实现前端前端静态资源的“hash 资源永久缓存 + 非 hash 资源协商缓存”,需结合 Nginx 的缓存头配置,针对不同类型资源设计差异化策略。核心思路是:**对带 hash 的指纹文件(如`app.8f3b.js`)设置长期强缓存,对无 hash 的文件(如`index.html`)使用协商缓存**,既以下是具体实现方案: ### 一、两种缓存策略的适用场景 | 资源类型 | 特征 | 缓存策略 | 目的 | | -------------- | ------------------------------------------------------------- | ---------- | -------------------------------------- | | 带 hash 的资源 | 文件名含唯一 hash(如`style.1a2b.css`),内容变化则 hash 变化 | 永久强缓存 | 一次缓存后不再请求,减少重复下载 | | 非 hash 的资源 | 文件名固定(如`index.html`、`favicon.ico`),内容可能动态更新 | 协商缓存 | 每次请求验证是否更新,确保获取最新内容 | ### 二、核心配置方案 通过`location`匹配不同资源类型,分别设置缓存头: ```nginx 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`:过期后必须向服务器验证是否更新。 ### 四、与前端打包的配合要点 1. **确保 hash 生成规则可靠**: 前端打包时,需保证“内容不变则 hash 不变,内容变化则 hash 必变”。例如: - Webpack:`contenthash`(基于文件内容生成 hash)。 - Vite:默认对静态资源生成 contenthash。 2. **避免 hash 资源依赖非 hash 资源**: 确保带 hash 的 JS/CSS 不引用无 hash 的资源(如`background: url(/img/bg.png)`),否则 bg.png 更新后,引用它的 CSS 因 hash 未变而无法更新。 解决方案:让被引用资源也带上 hash(如`bg.a1b2c3.png`)。 3. **index.html 必须无 hash**: 作为入口文件,`index.html`需通过协商缓存确保用户每次获取最新版本,从而加载新的 hash 资源。 ### 五、验证缓存是否生效 1. **强缓存验证**: 访问带 hash 的资源(如`app.8f3b.js`),在浏览器 Network 面板中查看: - 状态码为`200 OK (from disk cache)`或`200 OK (from memory cache)`。 - Response Headers 包含`Cache-Control: public, max-age=31536000, immutable`。 2. **协商缓存验证**: 访问`index.html`,刷新页面: - 第一次请求:状态码`200 OK`,Response Headers 有`Last-Modified`。 - 第二次请求:Request Headers 有`If-Modified-Since`,若未修改,状态码`304 Not Modified`。 ### 总结 通过 Nginx 实现“hash 资源永久缓存 + 非 hash 资源协商缓存”的核心是: 1. 利用 hash 文件名的唯一性,对静态资源设置长期强缓存,最大化减少重复请求。 2. 对入口文件等无 hash 资源启用协商缓存,确保内容更新时能被及时获取。 3. 前端打包与 Nginx 配置协同,保证 hash 机制可靠,避免缓存不一致问题。 这种策略既能大幅提升页面加载速度,又能确保资源更新的即时性,是前端性能优化的关键实践。
评论 (
0
)
登录
后才可以发表评论
状态
待办的
待办的
进行中
已完成
已关闭
负责人
未设置
标签
web应用场景
未设置
标签管理
里程碑
中
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
未关联
分支 (1)
标签 (64)
master
0.0.76
0.0.75
0.0.74
0.0.73
0.0.72
0.0.71
0.0.70
0.0.69
0.0.68
0.0.67
0.0.66
0.0.65
0.0.64
0.0.63
0.0.62
0.0.61
0.0.60
0.0.59
0.0.58
0.0.57
0.0.56
0.0.55
0.0.54
0.0.53
0.0.52
0.0.51
0.0.50
0.0.49
0.0.48
0.0.47
0.0.46
0.0.45
0.0.44
0.0.43
0.0.42
0.0.41
0.0.40
0.0.39
0.0.38
0.0.37
0.0.36
0.0.35
0.0.34
0.0.33
0.0.32
0.0.31
0.0.30
0.0.29
0.0.28
0.0.27
0.0.26
0.0.25
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
参与者(1)
TypeScript
1
https://gitee.com/yanleweb/interview-question.git
git@gitee.com:yanleweb/interview-question.git
yanleweb
interview-question
interview-question
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册