保存网页为单个文件/Save webpages All-in-one file

看到好的网页需要保存到本地的时候,有几种保存方式可选择,保存为网页文件(仅网页)的话,会得到一个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的基本使用格式如下:

data:[<MIME-type>][;base64|charset=some_charset],<data>

mime-type是嵌入数据的mime类型,比如png图片就是image/png。 如果后面跟base64,说明后面的data是采用base64方式进行编码的,毕竟数据都需要编码以免和其他的网页内容相冲突。所以如果不采用base64编码,就必须使用urlencode把数据进行转换,在这种情况下可以使用charset=来指定内容的字符集。

下面贴几个data: URI实际应用的例子,先看效果,再贴源码,注意我贴的源码中英文引号会被WP替换为中文引号,另外为了显示方便会增加一些回车换行,如果要复制到本地实验的话最好直接查看本页面的源代码。

首先是一个图片的例子,我的图片也许大了些,不过用来作qq自定义表情发给朋友还是不错滴。 这个图片用来作qq表情传给别人不错哦 注意这可是很“长”的一行哦,源代码:

<img src=”data:image/gif;base64, R0lGODlhIwGVAPecAHmCwQAA/yBKv+P1//z+/7zo/6De/9Hv/1FOhMbj+I2x7SBd1IGAlur4//7/ /0hGh9Tw/+by/HiX3Vh4y3iW28nt/5/e/zVjzUJruzVmzyA9ryA5qzhSteb2//X8//f8/93z/6jh ……(省略若干行) RT3asYpVxKLsEujHwTGxjqh8pTRp1zruHGEQX5CCEZhwgzj2cpSDzCErxThAQq5tfMEk5Sq/B8xX LlF/8FSm/6b5xynaUD3zTFwpa/cixHbu05BWfCcwT+lCfZJPn148nyfniEzRCbSVoKwWMRUWEAA7 ” alt=”这个图片用来作qq表情传给别人不错哦” />

下面是一个在inline css中嵌入背景图的例子: data: URI 源代码:

<span style=”padding-right: 20px; background: url(data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lE QVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQ AAAAAElFTkSuQmCC) top right no-repeat;”> data: URI</span>

再来一个嵌入javascript代码的例子,注意不同于上面两个例子,这次使用的是urlencode编码方式: 点一下这里–>Fwolf作品 源代码:

<script type=”text/javascript” src=”data:text/javascript;charset=utf-8,function%20test_urlencode_js%28%29%7Balert%28%27%E8%BF%99%E7%AE%97%E6%98%AF%E4%B8%80%E7%A7%8D%E5%8A%A0%E5%AF%86%E4%B9%88%EF%BC%9F%27%29%3B%7D”></script> <span onclick=”javascript:test_urlencode_js();”>点一下这里–&gt;Fwolf作品</span>

参考: 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),还不知道我的服务器能否支撑得住呢 :-)。

3 thoughts on “保存网页为单个文件/Save webpages All-in-one file”

  1. 我来解释下这个:

    在一些访问受限制的场合可以使用,比如一个web界面的超文本编辑器,就可以通过这种方式在编辑区中插入图片。

    所谓 web 界面超文本编辑器,就是常说的在线所见所得网页内容编辑器,比如 gmail 的文本框, 他们通常都是将一个 iframe 框架设为编辑模式(或将网页一个区域设为可编辑),再让你在里边编辑 html,

    通常在这种编辑里插入图片,都是插入的绝对地址,并不能将图片真正保存下来, (或者需要其他辅助手段先上传到服务器,再引用服务器上的地址,如 google doc)

    而使用内联图像,就可以将 base64 编码的图片内容直接附在 html 文本里,使得 html 可以独立而不需要外部连接文件

Leave a Reply

Your email address will not be published. Required fields are marked *