看到好的网页需要保存到本地的时候,有几种保存方式可选择,保存为网页文件(仅网页)的话,会得到一个html,但是不包含所有的图片等附加文件,保存为网页文件(全部)的话,会得到一个html文件和一个目录,图片等所有附加文件都在目录中,但是要想保存为一个文件并且所有的图片等附加文件还都完整的话,目前只有ie可以实现,那就是保存为mht文件,那么这个mht文件到底是什么呢?
mht其实是一种MHTML文件,MHTML是MIME HTML (Multipurpose Internet Mail Extension HTML)的简称,它的初衷是在邮件中嵌入HTML内容,RFC2557详细描述了文档定义。ie保存的mht文件、html格式的电子邮件、甚至chm文件都采用了MHTML或者相似的技术。
遗憾的是,不同的浏览器对mhtml的支持程度不尽相同,并且不同的浏览器保存的mhtml文件也不一定兼容(本部分内容主要参考自wikipedia):
IE: 自从1999年的ie5就支持保存为mht格式了,但在保存一些复杂页面的时候会出错。 Opera: 自从opera 9.0(build 8264, 发布于2006-3-10)起支持保存mhtml文件。 Firefox: mozilla、firefox系列浏览器到目前为止仍然不直接支持保存mhtml文件功能,虽然个人非常喜欢firefox,但是这的确是个缺点,甚至早在1999年就有人在Bugzilla上提出了这个问题,但没有得到开发人员的足够重视。不过倒是有个插件Mozilla Archive Format(地址二)填补了这一空白,但是目前只支持到ff1.5,针对ff2只有一个非官方的build。据说MAF生成的mht文件和微软系列不全兼容。 Safari: 自动2005年4月29日的2.0版本,苹果上的safari支持保存网页为mhtml文件,但是却不支持显示mhtml文件。
由于浏览器对mhtml的支持相当的不统一,mhtml的使用受到了很大的限制,就我个人的感觉,还是以微软系列的mht为主流,甚至kde上还有一款kmhtConvert软件,可以把微软的mht格式转换为kde的mhtml格式——war文件。
由于mhtml的原理,所有支持mhtml的浏览器或插件采用的方式大多是变相的文件打包的方式,也就是相当于把网页完整保存下来,然后把html文件和目录下的图片等其他文件通过某种方法进行大包,并更改html文件中的链接,通过特殊的链接格式引用包中的资源文件。其实,除了mhtml以外,我们还有另外一个选择,那就是data: URI scheme。
data: URI scheme和mhtml的不同之处在于,mhtml解决问题的方式是对多个文件打包,而data: URI则是直接把文件的内容包含在地址当中。比如我引用了一个图片文件http://www.fwolf.com/favorite.ico,mhtml的做法是把这个ico文件打包进去,而data: URI则是直接把地址http://www.fwolf.com/favorite.ico替换为诸如data: image/png; base64, iVBORw0KG…..这样的代码,从而实现所有的内容都在一个文件中的目的。
data: URI被大多数浏览器支持,并且语法由RFC2397定义,不同浏览器的处理效果基本一致,当然,和往常一样,不被ie系列支持。不过从我个人来讲,不管是windows平台还是linux平台,我都会选择firefox浏览器,所以可以无视掉ie。
当然data: URI也不是万能药水,它也有自己的优缺点:(本部分参考自wikipedia) 优点:
- 增加了web访问的请求次数,比如一个包含2个图片引用的网页文件,一共会产生3次web请求——一次是文件本身,另外两次分别是那两个图片。这样会节省一些网络资源,因为http协议是无状态协议,每次请求都一定的系统开销。
- 一般的浏览器默认配置都是最多同时使用2个连接访问服务器,所以请求次数的减少也节省了连接资源。有些web服务器从服务端也可以作类似的配置。
- 浏览器缓存中的文件数目减少了。
- 在一些访问受限制的场合可以使用,比如一个web界面的超文本编辑器,就可以通过这种方式在编辑区中插入图片。(不明白它在说什么)
- 我想这同样适用于需要隐藏图片地址的场合,因为图片的地址就是它的数据,而不是到你服务器上某个文件的链接,所以这一点对付图片盗链者来说简直太有效了。
- 可以避免页面采用https连接,图片等文件采用普通http连接所产生的“本页即包括安全内容,又包含不安全的内容”这样的情况。
- 最重要的一点,通过它可以实现把网页保存为一个单独的文件 :)。
缺点:
- 嵌入的内容在客户端要重新进行编码和显示,增加了一点点客户端系统开销。
- 如果同一项资源被多次引用,也只能重复嵌入它的数据,没有“重复利用”这一说,如果网页中同一个图片被显示了100次的话,数据量的增加是惊人的。
- 浏览器对URI长度通常都有限制,比如opera限制为4k,不过这只影响你把date: URI写到地址栏或者<a>标记中的情况。
- 不支持数据压缩,采用base64编码的数据体积会增加1/3,采用url-encode编码的数据体积会增加2倍。不过如果web服务器启用了压缩,这一点的影响就可以抵消了。
- 不被微软的IE支持。
data: URI的基本使用格式如下:
mime-type是嵌入数据的mime类型,比如png图片就是image/png。 如果后面跟base64,说明后面的data是采用base64方式进行编码的,毕竟数据都需要编码以免和其他的网页内容相冲突。所以如果不采用base64编码,就必须使用urlencode把数据进行转换,在这种情况下可以使用charset=来指定内容的字符集。
下面贴几个data: URI实际应用的例子,先看效果,再贴源码,注意我贴的源码中英文引号会被WP替换为中文引号,另外为了显示方便会增加一些回车换行,如果要复制到本地实验的话最好直接查看本页面的源代码。
首先是一个图片的例子,我的图片也许大了些,不过用来作qq自定义表情发给朋友还是不错滴。 注意这可是很“长”的一行哦,源代码:
下面是一个在inline css中嵌入背景图的例子: data: URI 源代码:
再来一个嵌入javascript代码的例子,注意不同于上面两个例子,这次使用的是urlencode编码方式: 点一下这里–>Fwolf作品 源代码:
参考: MHTML on wikipedia Maf extension project for mozilla & firefox Mozilla Archive Format on Firefox Addons RFC2557: MIME Encapsulation of Aggregate Documents, such as HTML (MHTML) Bugzilla: Full rfc2557 MHTML multipart/related support in BROWSER(from 1999) Using HTML in E-mail kmhtConvert data: URI scheme RFC2397: The “data” URL scheme Using Data URLs Effectively with Cascading Style Sheets HTML as media container format
后记 @ 2008-01-12
opera也支持mht格式了,包括它的linux版本,不知道从什么时候开始的。
其实这篇文章在2007年6月就写好了,当时就想着写一个小工具,利用data:URI这个特性,能够把网页都保存到一个文件当中去,然后再发表文章,可这一等就是半年多,终于利用2008年春节的空档时间,把这个工具已经写好了,有兴趣的可以[试一试](/tools/2008/save_html_all_in_one_file.php),还不知道我的服务器能否支撑得住呢 :-)。
我来解释下这个:
所谓 web 界面超文本编辑器,就是常说的在线所见所得网页内容编辑器,比如 gmail 的文本框, 他们通常都是将一个 iframe 框架设为编辑模式(或将网页一个区域设为可编辑),再让你在里边编辑 html,
通常在这种编辑里插入图片,都是插入的绝对地址,并不能将图片真正保存下来, (或者需要其他辅助手段先上传到服务器,再引用服务器上的地址,如 google doc)
而使用内联图像,就可以将 base64 编码的图片内容直接附在 html 文本里,使得 html 可以独立而不需要外部连接文件
谢谢解释,网页上的WYSIWYG可视化编辑器现在已经遍地都是了。
这个是直接用 firefox 转换图片的 javascript 书签 http://paste.ubuntu.org.cn/8753 将她拷到 firefox 地址栏运行就会转换了, 添加进书签后,就可以随时点击转换