MHTML文件如何在前端页面展示
MHTML文件如何在前端页面展示
需求背景:
目前在给证券公司做项目,但是在使用新系统的过程中,甲方还希望之前之前系统的历史记录可以看到。
最初制定的计划是项目组里面做数据的把原系统页面爬取下来,转成图片,直接给到前端即可。但是产品建议说把整个页面的html爬下来再展示更好,但是在爬取html的过程中出现了若干问题,总之最后做数据的把之前的历史记录爬成MHTML格式的给了后端,我在请求的时候后端把MHTML格式文件内容以字符串格式全部给到前端。
技术背景:
1. MHTML和HTML
特性 | HTML | MHTML |
---|---|---|
文件格式 | 纯文本文件,扩展名为.html 或.htm | 单一文件,扩展名为.mht 或.mhtml |
资源处理 | 外部资源通过链接引用 | 所有资源(如图片、CSS、JS)嵌入文件中 |
用途 | 用于创建和展示网页 | 用于保存完整网页,适合离线浏览 |
兼容性 | 所有浏览器均支持 | 部分浏览器支持(如IE、Edge) |
文件大小 | 较小,因资源未嵌入 | 较大,因包含所有资源 |
离线支持 | 需要外部资源在线访问 | 支持离线浏览,资源已嵌入 |
分享与保存 | 需附带外部资源 | 单一文件,便于分享和保存 |
总结:
- HTML:适合在线浏览,依赖外部资源。
- MHTML:适合保存完整网页,便于离线使用和分享。
2. mhtml2html
需要了解这个库的使用方式,其官网地址如下:mhtml2html - npm
3. 为什么需要 .window.document
?
原因 1:模拟浏览器环境
mhtml2html
的设计可能是为了在 Node.js 或浏览器中模拟一个独立的浏览器环境(类似jsdom
或iframe
),以正确解析 MHTML 文件的资源(如 CSS、图片、脚本等)。- 在这种情况下,生成的
convertedHTML
对象会包含一个完整的window
对象,其内部才有document
和documentElement
。
原因 2:隔离文档作用域
- MHTML 文件可能包含独立的 HTML、CSS 和 JavaScript 代码,需要在一个隔离的环境中运行,避免污染当前页面的全局作用域。
- 通过将文档封装在
window
对象中,mhtml2html
实现了这种隔离。
4. innerHTML和outerHTML
特性 | innerHTML | outerHTML |
---|---|---|
定义 | 获取或设置元素内部的 HTML 内容(不包含该元素本身) | 获取或设置整个元素的 HTML,包括该元素自身及其所有子元素 |
返回内容 | 返回元素内部的 HTML 字符串 | 返回包含当前元素标签及其内部 HTML 的完整字符串 |
修改行为 | 赋值后仅会替换元素内部的内容,不会改变元素自身 | 赋值后会替换整个元素(即当前元素及其所有子元素都会被更新或移除) |
常见用途 | 用于更新或操作元素内部的内容,例如动态加载文本或子节点 | 用于替换、删除整个元素,或将元素及其内容导出为 HTML 字符串 |
注意事项 | 修改后元素本身的标签和属性保持不变,仅子节点内容发生变化 | 修改后原来的 DOM 引用可能失效,因为整个元素可能已经被新元素替换 |
解决思路:
1. 使用iframe展示内容
1. 首先,你可能需要一个库来解析MHTML文件。可以使用`mhtml2html`库来将MHTML转换为HTML。
2. **Blob**: 用于创建一个包含HTML内容的Blob对象。
3. **URL.createObjectURL**: 生成一个临时的URL,用于在`iframe`中加载HTML内容。
核心代码示例:
<template><div><!-- 使用 iframe 展示 MHTML 内容 --><iframe :src="iframeSrc" width="100%" height="500px"></iframe></div>
</template><script>
import { ref, onMounted } from "vue";
import mhtml2html from "mhtml2html";export default {setup() {const iframeSrc = ref(""); // 用于存储 iframe 的 src// 加载并解析 MHTML 文件const loadMHTML = async () => {try {// 假设你有一个 MHTML 文件的 URLconst mhtmlUrl = "/path/to/your/file.mhtml";// 获取 MHTML 文件内容const response = await fetch(mhtmlUrl);const mhtmlContent = await response.text();// parse解析:将 MHTML 字符串解析为对象const parsedMHTML = mhtml2html.parse(mhtmlContent);// convert, 将 解析出的 MHTML 对象转译成含有资源的 HTMLconst convertedHTML = mhtml2html.convert(parsedMHTML);if (!convertedHTML?.window.document?.documentElement) {throw new Error("HTML转换失败,未找到可用的 documentElement");}// 注意:mhtml2html.convert 返回的是一个模拟的浏览器环境,其文档对象 (document) 必须通过 .window 访问。这种设计是为了隔离 MHTML 文件的内容,确保资源解析和样式作用域的正确性。直接使用 convertedHTML.document 会失败,因为 document 并未直接暴露在返回值顶层。const htmlContent =convertedHTML.window.document.documentElement.outerHTML;loadingText.value = "解析成功,开始展示";// 创建 Blob URLconst blob = new Blob([htmlContent], { type: "text/html" });iframeSrc.value = URL.createObjectURL(blob);} catch (error) {console.error("Failed to load MHTML file:", error);}};// 在组件挂载时加载 MHTML 文件onMounted(() => {loadMHTML();});// 在组件销毁时清理 Blob URLonBeforeUnmount(() => {if (iframeSrc.value) {URL.revokeObjectURL(iframeSrc.value);}});return {iframeSrc,};},
};
</script><style scoped>
iframe {border: 1px solid #ccc;
}
</style>
2. 使用v-html展示内容
本来想将解析出来的html文本内容直接通过v-html
展示,但是实际展示却是html字符串,所以不推荐使用这种方式。
总结:
实际上这个功能不算复杂,但是对于一些基础的前端知识先需要了解,否则会踩坑,有较长的试错时间。
相关文章:

MHTML文件如何在前端页面展示
MHTML文件如何在前端页面展示 需求背景: 目前在给证券公司做项目,但是在使用新系统的过程中,甲方还希望之前之前系统的历史记录可以看到。 最初制定的计划是项目组里面做数据的把原系统页面爬取下来,转成图片,直接给…...

学习笔记:在华为云ModelArts上运行MindSpore扩散模型教程
目录 一、背景与目的 二、环境搭建 三、模型原理学习 1. 类定义与初始化 2. 初始卷积层 3. 时间嵌入模块 4. 下采样模块 5. 中间模块 6. 上采样模块 7. 最终卷积层 8. 前向传播 9. 关键点总结 四、代码实现与运行 五、遇到的问题及解决方法 六、总结与展望 教程来源:…...

使用sharding-jdbc实现读写分离
简介 读写分离是一种数据库架构设计的模式,主要用于提高数据库的性能和可扩展性。它将数据库的读取操作和写入操作分离到不同的数据库实例上,从而优化系统的负载和响应速度。 实现前提是需要进行主从复制(数据层面的分离) 实现…...

“图像识别分割算法:解锁视觉智能的关键技术
嘿,各位朋友!今天咱们来聊聊图像识别分割算法。这可是计算机视觉领域里特别厉害的一项技术,简单来说,它能让机器“看懂”图像中的不同部分,并把它们精准地分出来。想象一下,机器不仅能识别出图里有猫还是狗…...

【Go语言快速上手】第二部分:Go语言进阶
文章目录 并发编程goroutine:创建和调度 goroutinechannel:无缓冲 channel、有缓冲 channel、select 语句无缓冲 channel有缓冲 channelselect 语句 sync 包:Mutex、RWMutex、WaitGroup 等同步原语Mutex:互斥锁RWMutex:…...

GRN前沿:GRETA:从多模式单细胞数据推断基因调控网络方法的比较与评价
1.论文原名:Comparison and evaluation of methods to infer gene regulatory networks frommultimodal single-cell data 2.发表日期:20254.12.21 摘要: 细胞通过基因表达调节其功能,由转录因子和其他调节机制的复杂相互作用驱…...

python基础入门:4.4模块与包管理
Python模块与包管理完全指南:构建可维护的代码结构 # 示例项目结构 """ my_package/ ├── __init__.py ├── core/ │ ├── __init__.py │ ├── utils.py │ └── calculator.py ├── data/ │ └── config.json └── tes…...

《XSS跨站脚本攻击》
一、XSS简介 XSS全称(Cross Site Scripting)跨站脚本攻击,为了避免和CSS层叠样式表名称冲突,所以改为了XSS,是最常见的Web应用程序安全漏洞之一,位于OWASP top 10 2013/2017年度分别为第三名和第七名&…...

LC-两数之和、字母异位词分组、最长连续序列、移动零、盛最多水的容器
两数之和 class Solution {public int[] twoSum(int[] nums, int target) {int n nums.length; // 获取数组 nums 的长度// 外层循环:遍历数组中的每一个元素 nums[i]for(int i 0; i < n; i) {// 内层循环:从 nums[i] 的下一个元素 nums[j] 开始遍…...

Netty源码解析之线程池的实现(二):创建线程与执行任务
前言 先看下面的代码: public class MyTest {public static void main(String[] args) {//创建NioEventLoopGroupNioEventLoopGroup loopGroup new NioEventLoopGroup(3);System.out.println(Thread.currentThread()"准备执行任务");//执行任务for (in…...

IDEA - 一个启动类多次启动方法
More Run/Debug -> Modify Run Configuration -> modify options -> Allow mutiple instances...

U3D支持webgpu阅读
https://docs.unity3d.com/6000.1/Documentation/Manual/WebGPU-features.html 这里看到已经该有的差不多都有了 WOW VFX更是好东西 https://unity.com/cn/features/visual-effect-graph 这玩意儿化简了纯手搓一个特效的流程 如果按原理说就是compute shader刷position&#…...

C++广度优先搜索
简介 老规矩,先来介绍一下什么是广度优先搜索(至于这么长时间没更新是为什么,我放在文章结尾了,感兴趣可以看看,以后也是如此) 广度优先搜索,从名字就能听出来,他和深度优先搜索关…...

SVN 提交与原有文件类型不一样的文件时的操作
SVN 提交与原有文件类型不一样的文件时的操作 背景 SVN 服务器上原本的文件是软链接类型的,但是我将它改成普通文件再上传。出现了以下提示: 解决过程 本来想着通过 svn rm 和 svn add 来解决,但是行不通。 最终解决方案 svn rm --keep-…...

活动预告 | Power Hour: Copilot 引领商业应用的未来
课程介绍 智能化时代,商业应用如何实现突破?微软全球副总裁 Charles Lamanna 将为您深度解析,剖析其中关键因素。 在本次线上研讨会中,Charles Lamanna 将分享他在增强商业运营方面的独到见解与实战策略,深度解读商业…...

WPF 进度条(ProgressBar)示例一
本文讲述:WPF 进度条(ProgressBar)简单的样式修改和使用。 进度显示界面:使用UserControl把ProgressBar和进度值以及要显示的内容全部组装在UserControl界面中,方便其他界面直接进行使用。 <UserControl x:Class"DefProcessBarDemo…...

【C#】任务调度的实现原理与组件应用Quartz.Net
Quartz 是一个流行的开源作业调度库,最初由 Terracotta 开发,现在由 Terracotta 的一部分 Oracle 所有。它主要用于在 Java 应用程序中调度作业的执行。Quartz 使用了一种复杂的底层算法来管理任务调度,其中包括任务触发、执行、持久化以及集…...

UV - Python 包管理
文章目录 创建 uv 项目已有项目已有uv项目 创建 uv 项目 # 创建项目 uv init m3 # 创建环境 cd m3 uv venv --python 3.11 # 激活环境 source .venv/bin/activate # 添加库 uv add flask 如果创建项目后,给库取别的名字,add 的时候,会…...

pytorch torch.linalg模块介绍
torch.linalg 是 PyTorch 的 线性代数 (Linear Algebra) 子模块,它提供了许多 高效的矩阵操作和分解方法,类似于 NumPy 的 numpy.linalg 或 SciPy 的 scipy.linalg,但针对 GPU 加速和自动微分 进行了优化。 1. 矩阵基本运算 矩阵乘法 torc…...

光伏-报告显示,假期内,硅料端签单顺序发货相对稳定。若3月份下游存提产,则不排除硅料价格有上调预期。
据TrendForce集邦咨询报告显示,假期内,硅料端按照前期签单顺序发货,相对稳定。若3月份下游存提产,则不排除硅料价格有上调预期。 002306中科云网 旅游 | 公司为提供复合菜系特色餐饮的连锁企业,形成了以粤菜ÿ…...

【web自动化】指定chromedriver以及chrome路径
selenium自动化,指定chromedriver,以及chrome路径 对应这篇文章,可以点击查看,详情 from selenium import webdriverdef get_driver():# 获取配置对象option webdriver.ChromeOptions()option.add_experimental_option("de…...

顺丰数据分析(数据挖掘)面试题及参考答案
你觉得数据分析人员必备的技能有哪些? 数据分析人员需具备多方面技能,以应对复杂的数据处理与解读工作。 数据处理能力:这是基础且关键的技能。数据常以杂乱、不完整的形式存在,需通过清洗,去除重复、错误及缺失值数据,确保数据质量。例如,在电商销售数据中,可能存在价…...

Android studio:顶部导航栏Toolbar
主流APP在顶部都配有导航栏,在 Android 中,ActionBar 是默认启用的,它是位于屏幕顶部的一个工具栏,用来放置应用的标题、导航和操作菜单。 如果你想使用自定义的 Toolbar 来替代 ActionBar,应该先关闭它。可以通过设置…...

mmap 文件映射
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 mmap介绍🦋 基本说明🦋 参数介绍🦋 返回值 二:🔥 demo代码🦋 写入映射🦋…...

基于微信小程序的医院预约挂号系统的设计与实现
hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的在校大学生…...

【Linux】Socket编程—UDP
🔥 个人主页:大耳朵土土垚 🔥 所属专栏:Linux系统编程 这里将会不定期更新有关Linux的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 文章目…...

2025年物联网相关专业毕业论文选题参考,文末联系,选题相关资料提供
一、智能穿戴解决方案研究方向 序号解决方案论文选题论文研究方向1智能腰带健康监测基于SpringBoot和Vue的智能腰带健康监测数据可视化平台开发研究如何利用SpringBoot和Vue技术栈开发一个数据可视化平台,用于展示智能腰带健康监测采集的数据,如心率、血…...

如何在WPS和Word/Excel中直接使用DeepSeek功能
以下是将DeepSeek功能集成到WPS中的详细步骤,无需本地部署模型,直接通过官网连接使用:1. 下载并安装OfficeAI插件 (1)访问OfficeAI插件下载地址:OfficeAI助手 - 免费办公智能AI助手, AI写作,下载…...

DeepSeek之Api的使用(将DeepSeek的api集成到程序中)
一、DeepSeek API 的收费模式 前言:使用DeepSeek的api是收费的 免费版: 可能提供有限的免费额度(如每月一定次数的 API 调用),适合个人开发者或小规模项目。 付费版: 超出免费额度后,可能需要按…...

使用DeepSeek实现AI自动编码
最近deepseek很火,低成本训练大模型把OpenAI、英伟达等股票搞得一塌糊涂。那它是什么呢,对于咱们程序员编码能有什么用呢?DeepSeek 是一款先进的人工智能语言模型,在自然语言处理和代码生成方面表现出色。它经过大量代码数据训练&…...