如何使用JS实现类Chrome另存为MHTML的网页下载功能
Chrome网页一键下载MHTML实现方案
首先明确前提:普通网页环境下的前端JS没有权限调用Chrome原生的MHTML生成接口,无法100%还原浏览器原生「另存为MHTML」的效果,根据使用场景可以选择以下几种可行方案:
方案1:开发Chrome扩展(效果最完美,和原生保存完全一致)
这是唯一能做到和Chrome手动另存MHTML效果无差别的方案,依赖Chrome官方提供的扩展API实现:
- 第一步编写扩展配置文件
manifest.json,声明必要权限,采用Manifest V3规范即可:
{ "manifest_version": 3, "name": "一键保存MHTML", "version": "1.0", "permissions": ["pageCapture", "activeTab", "downloads"], "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ], "background": { "service_worker": "background.js" } }
- 第二步编写
content.js,在目标页面注入下载按钮,监听点击事件后向扩展后台发消息:
// 示例:在页面插入自定义下载按钮 const saveBtn = document.createElement('button'); saveBtn.textContent = '保存当前页为MHTML'; saveBtn.addEventListener('click', () => { chrome.runtime.sendMessage({ type: 'triggerSave' }); }); document.body.appendChild(saveBtn);
- 第三步编写
background.js,调用官方接口生成MHTML并触发下载:
chrome.runtime.onMessage.addListener(async (msg, sender) => { if (msg.type !== 'triggerSave') return; // 调用Chrome原生MHTML生成接口 const mhtmlBlob = await chrome.pageCapture.saveAsMHTML({ tabId: sender.tab.id }); const blobUrl = URL.createObjectURL(mhtmlBlob); // 触发下载,默认文件名用当前页面标题 await chrome.downloads.download({ url: blobUrl, filename: `${sender.tab.title}.mhtml`, saveAs: false }); // 释放临时生成的Blob URL URL.revokeObjectURL(blobUrl); });
将三个文件放在同一文件夹,打开Chrome扩展管理页开启开发者模式,选择「加载已解压的扩展程序」选中该文件夹即可使用,生成的文件不会丢失资源、不会出现样式错乱问题。
方案2:纯前端模拟实现(仅限简单同域页面,效果有缺陷)
如果不想开发扩展,仅在自己可控的同域页面使用,可以手动拼接MHTML格式,但存在明显硬伤:
- 所有跨域的图片、样式、字体、iframe内容都无法正常获取,保存后会出现资源缺失
- 无法还原Chrome原生MHTML的标准头信息,部分浏览器、MHTML阅读器可能无法正常打开生成的文件
- 核心实现逻辑:遍历页面内所有资源,将可访问的资源转成base64格式内联到HTML中,按照MHTML要求的multipart邮件格式拼接所有内容和资源,最后生成Blob唤起浏览器下载。
注意:该方案不适合公开复杂页面,保存后大概率出现内容、样式错乱。
方案3:普通用户零开发快捷方式
如果不需要嵌入自定义按钮,直接用Chrome自带功能就能快速保存:
- Windows/Linux系统按
Ctrl+Shift+S,Mac系统按Cmd+Shift+S唤起另存为窗口,保存格式选择「网页,单个文件(.mhtml)」即可 - 如果需要默认保存为MHTML,可以给Chrome快捷方式添加启动参数
--save-page-as-mhtml,开启后所有网页另存默认就是MHTML格式。
内容的提问来源于stack exchange,提问作者Futeko TV
相关产品推荐
相关产品推荐

