Hexo博客缓存问题的终极解决方案
|Word Count:1.1k|Reading Time:4mins|Post Views:
问题描述
使用Hexo博客部署到GitHub Pages后,经常遇到一个困扰的问题:每次hexo deploy
部署后,博客的新内容在浏览器中不会立即显示,必须手动清理浏览器缓存(Ctrl+Shift+R)才能看到更新。
问题本质:浏览器会缓存CSS、JS等静态资源来优化性能,但当这些资源更新时,由于URL相同,浏览器继续使用旧的缓存内容。
1 2 3
| <link rel="stylesheet" href="/css/index.css" /> <script src="/js/main.js"></script>
|
解决方案
核心思路:为静态资源添加版本号,强制浏览器重新下载更新的文件。
方案设计
采用三层缓存控制机制:
- HTML页面缓存控制:通过Meta标签禁止缓存HTML
- 静态资源版本控制:为本地CSS/JS添加时间戳版本号
- CDN资源保护:保持第三方CDN资源不变
技术实现
创建scripts/cache-buster.js
文件,利用Hexo的after_render:html
钩子自动处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| hexo.extend.filter.register("after_render:html", function (str, data) { if (!str) return str;
const timestamp = Date.now();
str = str.replace( /(<link[^>]*href=["']?)([^"'?]+\.css)(\?[^"']*)?["']/g, (match, prefix, url, query) => { if ( url.includes("cdn.") || url.includes("://") || url.startsWith("http") ) { return match; } if (query && query.includes("v=")) { return match; } return `${prefix}${url}?v=${timestamp}"`; } );
str = str.replace( /(<script[^>]*src=["']?)([^"'?]+\.js)(\?[^"']*)?["']/g, (match, prefix, url, query) => { if ( url.includes("cdn.") || url.includes("://") || url.startsWith("http") ) { return match; } if (query && query.includes("v=")) { return match; } return `${prefix}${url}?v=${timestamp}"`; } );
return str; });
|
配置步骤
1. 添加HTML缓存控制
编辑主题模板文件themes/butterfly/layout/includes/head.pug
,添加:
1 2 3
| meta(http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate") meta(http-equiv="Pragma" content="no-cache") meta(http-equiv="Expires" content="0")
|
2. 启用CDN版本控制
编辑themes/butterfly/_config.yml
:
验证效果
命令行验证
1 2 3 4 5 6 7 8
| hexo clean && hexo generate
grep -n "\.css?v=" public/index.html
grep -n "\.js?v=" public/index.html
|
预期输出:
1 2
| 15:<link rel="stylesheet" href="/css/index.css?v=1690123456789" /> 28:<script src="/js/main.js?v=1690123456789"></script>
|
浏览器验证
- 部署博客后,打开开发者工具的Network面板
- 刷新页面,检查静态资源的URL是否包含版本号
- 再次部署,确认版本号已更新
使用说明
配置完成后,继续使用原有的Hexo工作流程即可:
1 2 3 4 5
| hexo clean && hexo generate && hexo deploy
hexo cl && hexo g && hexo d
|
每次执行hexo generate
时,系统会自动:
- 为所有本地CSS/JS文件添加当前时间戳
- 保持CDN资源链接不变
- 确保HTML页面不被缓存
扩展功能
支持更多资源类型
如需支持图片资源版本控制,可在脚本中添加:
1 2 3 4 5 6 7 8 9 10 11 12 13
| str = str.replace( /(<img[^>]*src=["']?)([^"'?]+\.(png|jpg|jpeg|gif|webp))(\?[^"']*)?["']/g, (match, prefix, url, ext, query) => { if (url.includes("cdn.") || url.includes("://") || url.startsWith("http")) { return match; } if (query && query.includes("v=")) { return match; } return `${prefix}${url}?v=${timestamp}"`; } );
|
环境区分
只在生产环境启用缓存清理:
1 2 3 4
| if (hexo.env.cmd === "generate" && process.env.NODE_ENV === "production") { }
|
总结
这个解决方案具有以下优点:
- 自动化:集成到Hexo生成流程,无需额外操作
- 智能化:区分本地资源和CDN资源,精确控制
- 兼容性:保持原有工作流程不变
- 高效性:最小化性能影响
配置完成后,每次部署博客内容都能立即更新,彻底解决缓存问题。