离线包资源必须用相对路径,动态加载需判断网络状态,版本更新需html内嵌校验逻辑,加密不可靠应后端校验,路由须用hash模式,错误需本地捕获。

离线包资源路径必须用相对路径,不能写绝对URL
打包后资源无法加载,90% 是因为 HTML 里写了 http:// 或 https:// 开头的引用。浏览器引擎(如 WebView2、CEF)在离线 EXE 环境中根本无法发起网络请求,所有资源必须本地可寻址。
实操建议:
- 把
<script src="https://cdn.jsdelivr.net/npm/vue@3"></script>换成下载后存为./libs/vue.3.min.js,再改写为<script src="./libs/vue.3.min.js"></script> - CSS/图片/字体同理,全部转为项目内相对路径,根目录以打包入口 HTML 文件为基准
- 检查
fetch()、XMLHttpRequest、iframe src等动态加载逻辑,离线环境下它们会静默失败,需提前判断navigator.onLine === false并 fallback 到本地 JSON 或缓存数据
版本更新必须带校验机制,否则用户可能运行旧包
HTML 离线包不像 App Store 那样自动强制更新,用户双击运行的永远是本地那个 EXE 文件。如果只是“重新打包再发新 EXE”,老用户不会自动切换——除非你主动破坏旧包兼容性或加一层启动检查。
实操建议:
- 在入口 HTML 中嵌入一个版本标识,比如
<meta name="app-version" content="2.3.1">,打包时由构建脚本注入真实版本号 - EXE 启动后读取该 meta 值,通过
getVersionAPI(如 HTML打包EXE 2.3.0 提供)比对服务端发布的最新版号,弹窗提示更新 - 关键逻辑不要只放在 JS 里:把校验逻辑写进 HTML 的
<script></script>标签内联执行,避免被缓存或绕过 - 若用 CHM 方案(如 HugeChm),版本控制更难——CHM 文件本身不支持运行时校验,只能靠文件名约定(如
help_v2.3.chm)+ 外部 launcher 检查
加密与资源保护不是“勾个选项”就完事
HTML 打包工具标称的“加密”通常只混淆 HTML/CSS/JS 文件内容,或对资源 ZIP 包加密码,但解密密钥仍硬编码在 EXE 内部。有经验的人用 Process Monitor + 内存 dump 就能还原出原始资源。
实操建议:
- 敏感逻辑(如授权验证、算法核心)不要放在前端,哪怕打包成 EXE —— 用
setRequestHeaders+ 后端接口做关键校验,前端只负责 UI 和 token 透传 - 若必须离线,把校验逻辑拆到 Node.js 层(如用 NW.js),利用
require('crypto')做本地机器码绑定,比纯前端 JS 更难逆向 - HugeChm 打包的 CHM 文件可用
hh.exe -decompile直接解包,所谓“加密”仅防小白;真正要保护内容,得用 DRM 或服务端渲染 - 图标、启动图、菜单栏这些 UI 元素可被轻易替换,别把版权信息或水印只放在这里
多页应用打包时,路由模式必须设为 hash
History 模式依赖服务器返回 404 页面重定向到 index.html,而离线 EXE 里没有服务器。一旦用户刷新页面或直接访问 /user/profile 这类 URL,就会看到白屏或 404 错误。
实操建议:
- Vue Router / React Router 必须显式配置
history: createWebHashHistory(),确保所有路由都带#前缀 - Webpack 的
html-webpack-plugin要关掉minify.removeScriptTypeAttributes,某些旧版 CEF 会因 script 标签缺type="text/javascript"报错 - 静态资源引用路径若含
public/,打包前确认它已复制进输出目录,且html-webpack-plugin的template路径指向正确位置
window.addEventListener('error') 和 Promise.catch,把错误序列化后写进本地 localStorage 或生成临时日志文件,下次启动时上传(如有网)或供用户手动导出。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











