Data URI 和 MHTML

Data URI

Data URI是由RFC 2397定义的一种把小文件直接嵌入文档的方案。通过如下语法就可以把小文件变成指定编码直接嵌入到页面中:

data:[<MIME-type>][;base64],<data>
  1. MIME-type:指定嵌入数据的MIME。其形式是[type]/[subtype]; parameter,比如png图片对应的MIME是image/png。parameter可以用來指定附加的信息,更多情況下是用于指定text/plain和text/htm等的文字编码方式的charset参数。默认是text/plain;charset=US-ASCII。
  2. base64:声明后面的数据的编码是base64的,否则数据必须要用百分号编码(即对内容进行urlencode)。

在上个世纪HTML4.01引入了Data URI方案,到今天为止除了IE6和IE7之外,所有主流浏览器都支持,但IE8对Data URI的支持还是有限制的,只支持object(仅是图片时)、img、input type=image、link和CSS中的URL,且数据量不能大于32K。

优点:

  1. 减少HTTP请求数,没有了TCP连接消耗和同一域名下浏览器的并发数限制。
  2. 对于小文件会降低带宽。虽然编码后数据量会增加,但是却减少了http头,当http头的数据量大于文件编码的增量,那么就会降低带宽。
  3. 对于HTTPS站点,HTTPS和HTTP混用会有安全提示,而HTTPS相对于HTTP来讲开销要大更多,所以Data URI在这方面的优势更明显。
  4. 可以把整个多媒体页面保存为一个文件。

缺点:

  1. 无法被重复利用,同一个文档应用多次同一个内容,则需要重复多次,数据量大量增加,增加了下载时间。
  2. 无法被独自缓存,所以其包含文档重新加载时,它也要重新加载。
  3. 客户端需要重新解码和显示,增加了点消耗。
  4. 不支持数据压缩,base64编码会增加1/3大小,而urlencode后数据量会增加更多。
  5. 不利于安全软件的过滤,同时也存在一定的安全隐患。

MHTML

MHTML是MIME HTML (Multipurpose Internet Mail Extension HTML)的缩写,是由RFC 2557定义的把一个多媒体的页面所有内容都保存到同一个文档解决方案。这个方案是由微软提出从IE5.0开始支持,另外Opera9.0也开始支持,Safari可以把文件保存为.mht(MHTML文件的后缀)格式,但不支持显示它。

MHTML和Data URI还比较类似,有更强大的功能和更复杂的语法,并且没有Data URI中“无法被重复利用”的缺点,但MHTML使用起来不够灵活方便,比如对资源引用的URL在mht文件中可以是相对地址,否则必须是绝对地址。hedger在《Cross Browser Base64 Encoded Images Embedded in HTML》针对IE的解决方案使用的是相对路径就是因为声明了Content-type:message/rfc822使IE按照MHTML来解析,如果不修改Content-type则需要使用MHTML协议,这个时候必须使用绝对路径,如《MHTML – when you need data: URIs in IE7 and under》

应用

Data URI和MHTML两者的配合可以完整的解决所有的主流浏览器,它们由于无法被缓存和重复利用的缺陷,所以并不适合直接在页面中使用,但在CSS和JavaScript文件中对图片适当地使用有非常大的优越性:

  1. 大大减少请求数,现在大型网站的CSS引用了大量的图片资源。
  2. CSS和JavaScript都可以被缓存,间接的实现了数据的缓存。
  3. 利用CSS可以解决Data URI的重复利用问题
  4. 告别CSS Sprites,CSS Sprites的出现是为了减少请求数,但它除了带来在不确定情况下的异常外,CSS Sprites还需要人为的图片合并,即使有合并工具也依旧必须人为地在如何有效的拼图上耗费大量的时间,并带来维护的困难。当你遵循一定的设计原则后,你就可以完全抛弃CSS Sprites来编写CSS,最后使用工具在上传到服务器环节把图片转换成Data URI和MHTML,如《利用data-uri合并样式表和图片》中用python实现的工具,这可以节约大量的时间。
  5. base64编码把图片文件增加了1/3,Data URI和MHTML同时使用相当于增加了2/3,但CSS和JavaScript可以使用gzip压缩,其可以节省2/3的数据量,所以使用gzip压缩后的最终数据量是(1 + 1/3) * 2 * (1/3) = 8/9,所以最终流量是减少的。

为了方便在CSS中实现Data URI和MHTML,我写了一个Data URI & MHTML 生成器,你可以看利用其生成Data URI & MHTML应用实例

在CSS文件中使用应用MHTML时URL必须使用绝对路径,导致非常不灵活,所以可以考虑使用CSS expression来解决(DEMO),比如:

   /*

http://old9.blogsome.com/2008/10/26/css-expression-reloaded/

http://dancewithnet.com/2009/07/27/get-right-url-from-html/

   */
  *background-image:expression(function(ele){
    ele.style.backgroundImage = 'url(mhtml:' +
         document.getElementById('data-uri-css').getAttribute('href',4) +
         '!03114501408821761.gif)';
   }(this));

标签:, , ,

作者:秦歌,时间:2009-08-15 0:54,归纳于:HTML & CSS,订阅:RSS 2.0,引用:Trackback

有评论 36 条,发表一条新评论 »

小马说:2009-08-16 10:09 #1

最佳实践的探索还需要时间,IE6目前的市场占用率还是让我有些悲观。

adrian说:2009-08-16 13:33 #2

感谢分享。

悉尼说:2009-08-16 17:39 #3

好文章啊!!
谢谢分享呢

gxd305说:2009-08-17 9:01 #4

datauri 能否动态赋值,那么mhtml 可以吗?

比如上传图片的俄时候,可以使用datauri可以很快显示缩略突。

mhtml 可以做到这点吗?

gxd305说:2009-08-17 9:01 #5

​datauri​ ​​能​​够动​​态​​赋​​值​​,​​那​​么​mhtml​ ​​可​​以​​吗​​?

上面那个字写错了。

emptyhua说:2009-08-17 11:08 #6

咔咔,分析的比较透,俺写过一个可以整个目录应用data-uri的脚本

秦歌说:2009-08-17 12:58 #7

@gxd305:IE6、IE7下的上传图片缩略图预览不需要使用MHTML,直接使用js就可以搞定,可以看hedger的项目http://code.google.com/p/image-upload-preview/
@emptyhua:你的脚本我看过,这篇帖子中有其链接,呵呵。

阿熊说:2009-08-18 10:10 #8

好东东,收藏研究研究

zerodaiy说:2009-08-18 12:49 #9

曾经想用于优化,无果,顶一下~ 个人觉得在实际应用中还是有一些难度的~

Betty说:2009-08-23 18:33 #10

同一个图片出现多次的时候,是必须重复所有的编码还是不必重复,引用一下就可以了?
另,您这里评论输入框的似乎字号太小了……

秦歌说:2009-08-24 0:01 #11

@Betty:使用Data URI时同一个图片出现多次的时候,如果直接使用就需要重复所有的编码,所以需要我们修改一下设计思路,比如我们通过继承只出现图片的url一次,或者给图片一个特定的类。如果使用MHTML只需要一次编码,后面紧紧是引用。
另外输入框的字号默认是12px,很影响使用么?可以考虑变大。

Betty说:2009-09-07 10:08 #12

谢谢
在我这里看,输入框的字小到几乎看不清,可否改成和正文一样大?

秦歌说:2009-09-07 12:18 #13

已经增大一个级别,请再看看。不知道你的浏览器和屏幕的分辨率如何,一般来讲12px应该是没有问题的啊。

陈成的博客 — Data URI小试 —— 在旺旺点灯(JS)上的应用说:2009-10-28 21:01 #14

[...] 本文重在实践和测试,如果你还不了解Data URI,推荐先阅读秦歌的Data URI 和 MHTML。 [...]

cloudgamer说:2009-12-22 22:19 #15

JavaScript 图片预览效果…

随着浏览器安全性的提高,要实现图片预览也越来越困难。不过群众的智慧是无限的,网上也有很多变通或先进的方法来实现。在研究了各种预览方法后,作为总结,写了这个程序,跟大家一起分享。上次写的简便无刷新文件上……

有米啦 » 详解Data URIs说:2010-01-05 15:16 #16

[...] 相关文章介绍:Data URI 和 MHTML –from 秦歌 对于DataURI 和MHTML 解析很详细 468 X 60 [...]

jack说:2010-01-31 1:08 #17

楼上某位说的输入框太小,是使用IE8的浏览器么?貌似IE8下的输入框会因为未知原因变得很小

关于DATA URI scheme « Depth Digger`s Den [深挖兽的巢穴]说:2010-02-22 14:00 #18

[...] 从这两篇博文找到了很有价值的东西: Data URI 和 URL Data URI 和 MHTML DATA URI [...]

JavaScript组件打包模式 - 样式之美说:2010-04-05 16:37 #19

[...] image:CSS里用的图片用dataURI(RFC 2397)跟MHTML(RFC 2557)的方式编到js里面。(秦歌写的dataURI和MHTML依然推荐给不知道是什么东东的同学看)。CSS里如果要绝对路径同样可以存js,js如果有直接用到的理论上也是可以,但js通常只改className会比较好。 [...]

tokki说:2010-04-06 10:29 #20

真正实施的话 要考虑太多东西

Data URI&MHTML: 用还是不用? « 99css说:2010-05-16 17:52 #21

[...] 秦歌的Data URI 和 MHTML [...]

Data URI&MHTML: 用还是不用?-传播、沟通、分享-一直“有你”说:2010-05-16 21:36 #22

[...] 秦歌的Data URI 和 MHTML [...]

zebo说:2010-05-18 20:51 #23

受教~~

在服务端合并和压缩JavaScript和CSS文件 @ 随网之舞说:2010-06-10 22:35 #24

[...] Sprites、图像映射(Image Map)和使用Data URI来编码图片。CSS Sprites和图像映射现在已经随处可见了,但由于IE6和IE7不支持Data [...]

在服务端合并和压缩JavaScript和CSS文件 « 可乐加糖说:2010-06-11 9:05 #25

[...] Sprites、图像映射(Image Map)和使用Data URI来编码图片。CSS Sprites和图像映射现在已经随处可见了,但由于IE6和IE7不支持Data [...]

在服务端合并和压缩JavaScript和CSS文件说:2010-06-12 9:52 #26

[...] Sprites、图像映射(Image Map)和使用Data URI来编码图片。CSS Sprites和图像映射现在已经随处可见了,但由于IE6和IE7不支持Data [...]

[zt]在服务端合并和压缩 JavaScript和CSS文件 « interUI说:2010-07-03 1:24 #27

[...] Sprites、图像映射 (Image Map)和使用Data URI来编码图片。CSS Sprites和图像映射现在已经随处可见了,但由于IE6和IE7不支持Data [...]

匿名说:2010-08-09 17:56 #28

RSS怎么在google reader下看不了了

关于Data URI的资料【也就是图片转成代码插入网页】 « 付琦 博客说:2010-08-12 17:57 #29

[...] 需要 Data URI 和 MHTML 配合 Data URI 和 MHTML 的解释 http://dancewithnet.com/2009/08/15/data-uri-mhtml/ 在线生成base64编码的图片http://dancewithnet.com/lab/2009/data-uri-mhtml/create.php [...]

Data URI & MHTML小结 | rains's blog说:2010-10-31 19:27 #30

[...] Data URI 和 MHTML MHTML在ie7/vista bug 解决方案 Data URI小试 —— [...]

小鱼儿 » Blog Archive » 在服务端合并和压缩JavaScript和CSS文件(转)说:2010-11-14 14:47 #31

[...] Sprites、图像映射(Image Map)和使用Data URI来编码图片。CSS Sprites和图像映射现在已经随处可见了,但由于IE6和IE7不支持Data [...]

在服务端合并和压缩JavaScript和CSS文件 | Wang Jun's Blog说:2010-11-24 16:34 #32

[...] Sprites、图像映射(Image Map)和使用Data URI来编码图片。CSS Sprites和图像映射现在已经随处可见了,但由于IE6和IE7不支持Data [...]

UXRen | 用户体验那些人 | 资讯频道 » 在服务端合并和压缩JavaScript和CSS文件说:2010-11-29 18:40 #33

[...] Sprites、图像映射(Image Map)和使用Data URI来编码图片。CSS Sprites和图像映射现在已经随处可见了,但由于IE6和IE7不支持Data [...]

JerryQu的小站 » 两个激进的前端优化手段说:2011-03-16 17:56 #34

[...] 既然是玩自己的博客程序,当然要发挥可以随意折腾的优势。除了拼大图之外,一个可行的方案是把图片弄成DataURI/MHTML放进css里,大家很早就开始这样玩了。前段时间我也写过一个py脚本来实现这个功能,因为有风险还没在项目中采用,正好拿来试试。跑完脚本后,背景图片都替换成了下面这样的: [...]

【整理收藏】合併、圧缩jsやcssファイル減少ページhttp請求の数の方法だ | テクニカルブログ说:2011-07-19 15:47 #35

[...] spritesだった、画像イメージング(image map)と党の中央に使うコーディングイラストです。data。css [...]

格物志 » 提升页面性能:减少HTTP请求的方法说:2011-10-15 13:37 #36

[...] 参考:Data URI 和 MHTML @ 随网之舞 [...]

发表一条评论

您可以在下面评论内容中使用下列XHTML标签:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


回到页眉