一、前言                                

上周五公司内部的Any Topic Conf.上我和同事们分享了这个主题,有同事说这个有用,有同事说这个没啥用,后来还延伸到网站性能的话题上,大家讨论的激烈程度让我觉得这次选题还不错。本篇先不管到底有用与否,仅仅记录理论知识。也希望大家一起来分享实战经验啊!

二、从HTTP URI Scheme入手                        

对于 <a href="http://github.com">HTTP URI Scheme</a> 我想大家都应该很熟悉了,href属性值http://github.com就是HTTP URI Scheme,那么什么是DATA URI Scheme呢?其实就是形如data:text/jpeg;base64,XINGSXXIANGJIJIGSAG==的资源链接,一般出现在img元素的src属性。

DATA URI Scheme的作用,一般就是将经过Base64编码的数据嵌入网页中,从而减少请求资源的链接数。上面的DATA URI Scheme中 base64, 后的字符就是经过base64编码后的数据,浏览器会对其解码并渲染该图片资源。

三、Data URI Scheme格式                                  

data:[<mime type>][;charset=<charset>][;<encoding>],<encoded data>

①.  data :协议名称;

②.  [<mime type>] :可选项,数据类型(image/png、text/plain等)

③.  [;charset=<charset>] :可选项,源文本的字符集编码方式

④.  [;<encoding>] :数据编码方式(默认US-ASCII,BASE64两种)

⑤.  ,<encoded data> :编码后的数据

注意:

 [a].  [<mime type>][;charset=<charset>] 的缺省值为HTTP Header 中Content-Type的字段值;

[b].  [;<encoding>] 的默认值为US-ASCII,就是每个字符会编码为%xx的形式;

 [c].  [;charset=<charset>] 对于IE是无效的,需要通过 charset 设置编码方式;而Chrome则是 charset 属性设置编码无效,要通过 [;charset=<charset>] 来设置;FF就两种方式均可。

[d]. 若 ,<encoded data> 不是以 [;<encoding>] 方式编码后的数据,则会报异常

四、示例                          

/**
* data:,文本数据
* data:text/plain,文本数据
* data:text/html,HTML代码
* data:text/css;base64,css代码
* data:text/javascript;base64,javascript代码
* data:image/x-icon;base64,base64编码的icon图片数据
* data:image/gif;base64,base64编码的gif图片数据
* data:image/png;base64,base64编码的png图片数据
* data:image/jpeg;base64,base64编码的jpeg图片数据,示例:
*/
body { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC");} /**
* data:text/css,css代码,示例:
* 注意:下列方式是无法设置background-image:url()样式的
*/
<link rel="stylesheet" type="text/css" href="data:text/css;charset=gbk,#pseudo{color:red;}"/> //data:text/javascript,javascript代码,示例:
<script type="text/javascript" charset="gbk" src="data:text/javascript;charset=gbk,alert('%D6%D0%CE%C4')"></script>

五、优点&缺点                        

 优点:

  ①. 减少资源请求链接数。

 缺点:

  ①. 不会被浏览器缓存起来;
  ②. 移动端性能比http URI scheme低。
 

六、优化方案                          

 通过在css文件的background-image样式规则使用Data URI Scheme,使其随css文件一同被浏览器缓存起来。

七、浏览器支持                          

 ①. 支持
  Opera 7.2+ data URI 必须小于4100字符
  IE8+ data URI必须小于32k(IE8不支持js的data URI)
  Chrome、FF和Safari无限制
 ②. 不支持
  IE567
 

八、标签支持                            

嵌入图片的object、img、input[type=image]、script、link和css规则中的background和backgroundImage属性

九、IE678的polyfill方案——MHTML                

MHTML(MIME HTML,Multipurpose Internet Mail Extensions HyperText Markup Language),就是将Data URI以附件的形式附加到页面页面上,具体示例如下:

/** FilePath: http://example.com/test.css */
/*!@ignore
Content-Type: multipart/related; boundary="_ANY_SEPARATOR" --_ANY_SEPARATOR
Content-Location:myidBackground
Content-Transfer-Encoding:base64 iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
--_ANY_SEPARATOR--
*/ .myid {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==");
*background-image: url(mhtml:http://example.com/test.css!myidBackground);
}

上面注释的部分就是定义一个名为myidBackground的Base64编码图片,然后在class为myid的css中使用。

注意:1、boundary字段值可自定义;

2、附件的末行必须为boundary字段值;

3、附件内容不能被压缩工具擦写掉;

4、由于高版本的IE在使用IE8兼容模式时能认识*这个css hack,但却不支持mhtml,所以会导致背景图片失效。应该采用IE的条件注释更为稳妥。

十、安全问题                           

当在IE6/7的HTTPS页面中使用Data URI时会提醒

MS 的解释是:

您正在查看的网站是个安全网站。它使用了 SSL (安全套接字层)或 PCT(保密通讯技术)这样的安全协议来确保您所收发信息的安全性。
当站点使用安全协议时,您提供的信息例如姓名或信用卡号码等都经过加密,其他人无法读取。然而,这个网页同时包含未使用该安全协议的项目

也就是说问题在scheme字段上,由于全站都采用https的scheme,而data scheme则被视为不安全的协议了。

十一、应用                           

1. 绕过浏览器过滤

// 绕过浏览器过滤
http://example.com/text.php?t="><script src="data:text/html,<script>alert("Xss")</script><

2. 批量请求图片

$.get('http://imgs.foo.com', {ids:[,,,,,,]}, function(data){
var imgs = []
data.each(function(i, dataUri){
imgs.push($(['<img src="data:image/jpeg;base64,', dataUri, '"/>'].join('')))
})
$(body).append(imgs)
})

十二、完全理解Base64编码                      

Base64字符集: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

  字节与字符映射关系(十进制):从0开始到63
  原理:

  对以某编码方式编码后的字节数组为对象,以3个字节为一组,按顺序排列24bit数据,然后以6bit一组分成4组;再在每组的最高位补2个0凑足一个字节。这时一组就有4个字节了。若字节数组不是3的倍数,那么最后一组就填充1到2个0字节。

然后按Base64编码方式(就是映射关系)对字节数组进行解码,就会得到平时看到的Base64编码文本。对于字节数组不是3的倍数,最后一组填充1到2个0字节的情况,填补的0字节对应的是=(等号)。
  示例:
 ①. 对AB进行ASCII编码:得到A()B()
②. 转成二进制形式:得到A()B()
③. 以3个字节为一组,非3的倍数补0字节:
④. 以6bit为一组后高位补两个0:( )( )( )( )
⑤. 转为十进制:()()()()
⑥. 根据映射关系解码:QUI=

十三、总结                          

Data URI Scheme就介绍到这里吧,各位一起来分享实战经验吧!

尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/3903688.html  ^_^肥仔John

 
十四、THANKS                          
http://www.cnblogs.com/hustskyking/p/data-uri.html(待整理)
 

JS魔法堂:Data URI Scheme介绍的更多相关文章

  1. JS魔法堂:LINK元素深入详解

    一.前言 我们一般使用方式为 <link type="text/css" rel="stylesheet" href="text.css&quo ...

  2. JS魔法堂:jsDeferred源码剖析

    一.前言 最近在研究Promises/A+规范及实现,而Promise/A+规范的制定则很大程度地参考了由日本geek cho45发起的jsDeferred项目(<JavaScript框架设计& ...

  3. JS魔法堂:IMG元素加载行为详解

    一.前言 在<JS魔法堂:jsDeferred源码剖析>中我们了解到img元素加载失败可以作为函数异步执行的优化方案,本文打算对img元素的加载行为进行更深入的探讨. 二.资源加载的相关属 ...

  4. JS魔法堂:属性、特性,傻傻分不清楚

    一.前言 或许你和我一样都曾经被下面的代码所困扰 var el = document.getElementById('dummy'); el.hello = "test"; con ...

  5. JS魔法堂:不完全国际化&本地化手册 之 实战篇

    前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...

  6. JS魔法堂:那些困扰你的DOM集合类型

    一.前言 大家先看看下面的js,猜猜结果会怎样吧! 可选答案: ①. 获取id属性值为id的节点元素 ②. 抛namedItem is undefined的异常 var nodes = documen ...

  7. 网页优化URI(http URI scheme与data URI scheme)

    网页优化的一大首要任务是减少HTTP 请求 (http request) 的次数,例如通过合并多个JS文件,合并CSS样式文件.除此之外,还有一个data URL 的密技,让我们直接把图像的内容崁入网 ...

  8. 关于 Data URI Scheme -- data:image/jpg;base64

    转载一篇大神的文章 大家可能注意到了,网页上有些图片的src或css背景图片的url后面跟了一大串字符,比如: data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqA ...

  9. Data URI Scheme,base64

    一.从HTTP URI Scheme入手 对于 <a href="http://github.com">HTTP URI Scheme</a> 我想大家都应 ...

随机推荐

  1. OA(权限管理初步模块)

    权限管理:一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源,不多不少.权限管理几乎出现在任何系统里面,只要有用户和密码的系统. 根据权限管理的套路,我们一般从这三个角 ...

  2. 如何通过倾斜摄影数据手动配置s3c索引文件?

    如何通过倾斜摄影数据手动配置s3c索引文件? 大家知道,倾斜摄影数据最常见的是OSGB格式,并且是由一个一个的Tile分级文件夹构成的Data文件夹.结构一般如下图所示: 那么,如何才能把模型的各个瓦 ...

  3. 05.DOM

    DOM基础 什么是DOM 标签元素节点浏览器支持情况  火狐支持最好 谷歌其次 ie最差 尤其是ie6-8DOM节点节点分为:元素节点和文本节点 测试节点的类型用nodeTypenodeType 为3 ...

  4. C++中的显式类型转化

    类型转化也许大家并不陌生,int i; float j; j = (float)i; i = (int)j; 像这样的显式转化其实很常见,强制类型转换可能会丢失部分数据,所以如果不加(int)做强制转 ...

  5. JS 怎么控制某个div的滚动条滚动到顶部? (已解决)

    获取这个元素,然后设置它的滚动条的位置为初始位置(0,0). document.getElementById(..).scrollTop = 0;

  6. Android课程---关于数据存储的学习(3)之数据库和事务

    DataActivity3.java package com.hanqi.test5; import android.content.ContentValues; import android.dat ...

  7. 异步网络加载开源框架AsyncHttpClient使用

    AsyncHttpClient是异步的,但是有时候我们需要得到请求的结果集来返回给某个函数,由于是异步的,所以不能够直接return会去,所以可以定义一个interface来给调用AsyncHttpC ...

  8. Linux系统的理解及学习Linux内核的心得

    作业列表      (点击作业跳转) linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作 linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核 ...

  9. 利用结果集元数据将查询结果封装为map

    package it.cast.jdbc; import java.sql.Connection; import java.sql.ParameterMetaData; import java.sql ...

  10. 挡不住的好奇心:ASP.NET 5是如何通过XRE实现跨平台的

    .NET程序员也有自己的幸福,.NET的跨平台是一种幸福,.NET的开源也是一种幸福,而更幸福的是可以通过开源的.NET了解.NET是如何一步步走向跨平台的,所以幸福是一种过程. 在.NET跨平台的进 ...