1、前言 javascript
上周五公司内部的Any Topic Conf.上我和同事们分享了这个主题,有同事说这个有用,有同事说这个没啥用,后来还延伸到网站性能的话题上,你们讨论的激烈程度让我以为此次选题还不错。本篇先无论到底有用与否,仅仅记录理论知识。也但愿你们一块儿来分享实战经验啊!php
2、从HTTP URI Scheme入手 css
对于 <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属性。html
DATA URI Scheme的做用,通常就是将通过Base64编码的数据嵌入网页中,从而减小请求资源的连接数。上面的DATA URI Scheme中 base64, 后的字符就是通过base64编码后的数据,浏览器会对其解码并渲染该图片资源。java
3、Data URI Scheme格式 git
data:①[<mime type>]②[;charset=<charset>]③[;<encoding>]④,<encoded data>⑤github
①. 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>] 方式编码后的数据,则会报异常
4、示例
/** * 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>
5、优势&缺点
优势:
①. 减小资源请求连接数。
缺点:
6、优化方案
经过在css文件的background-image样式规则使用Data URI Scheme,使其随css文件一同被浏览器缓存起来。
7、浏览器支持
8、标签支持
嵌入图片的object、img、input[type=image]、script、link和css规则中的background和backgroundImage属性
9、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中使用。
注意:一、boundary字段值可自定义;
二、附件的末行必须为boundary字段值;
三、附件内容不能被压缩工具擦写掉;
四、因为高版本的IE在使用IE8兼容模式时能认识*这个css hack,但却不支持mhtml,因此会致使背景图片失效。应该采用IE的条件注释更为稳妥。
10、安全问题
当在IE6/7的HTTPS页面中使用Data URI时会提醒
MS 的解释是:
您正在查看的网站是个安全网站。它使用了 SSL (安全套接字层)或 PCT(保密通信技术)这样的安全协议来确保您所收发信息的安全性。
当站点使用安全协议时,您提供的信息例如姓名或信用卡号码等都通过加密,其余人没法读取。然而,这个网页同时包含未使用该安全协议的项目。
也就是说问题在scheme字段上,因为全站都采用https的scheme,而data scheme则被视为不安全的协议了。
11、应用
1. 绕过浏览器过滤
// 绕过浏览器过滤 http://example.com/text.php?t="><script src="data:text/html,<script>alert("Xss")</script><
2. 批量请求图片
$.get('http://imgs.foo.com', {ids:[1,2,3,4,5,6,7]}, function(data){ var imgs = [] data.each(function(i, dataUri){ imgs.push($(['<img src="data:image/jpeg;base64,', dataUri, '"/>'].join(''))) }) $(body).append(imgs) })
12、彻底理解Base64编码
Base64字符集: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
对以某编码方式编码后的字节数组为对象,以3个字节为一组,按顺序排列24bit数据,而后以6bit一组分红4组;再在每组的最高位补2个0凑足一个字节。这时一组就有4个字节了。若字节数组不是3的倍数,那么最后一组就填充1到2个0字节。而后按Base64编码方式(就是映射关系)对字节数组进行解码,就会获得平时看到的Base64编码文本。对于字节数组不是3的倍数,最后一组填充1到2个0字节的状况,填补的0字节对应的是=(等号)。
①. 对AB进行ASCII编码:获得A(65)B(66) ②. 转成二进制形式:获得A(01000001)B(01000010) ③. 以3个字节为一组,非3的倍数补0字节:010000010100001000000000 ④. 以6bit为一组后高位补两个0:(00 010000)(00 010100)(00 001000)(00 000000) ⑤. 转为十进制:(16)(20)(8)(0) ⑥. 根据映射关系解码:QUI=
十3、总结
Data URI Scheme就介绍到这里吧,各位一块儿来分享实战经验吧!
尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/3903688.html ^_^肥仔John