JS魔法堂:Data URI Scheme介绍

简介:

一、前言                                

  上周五公司内部的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时会提醒

                  细说 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:[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)
})

十二、完全理解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(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=

十三、总结                          

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

目录
相关文章
|
JavaScript
js: 获取标签元素data-*属性值的方法
js: 获取标签元素data-*属性值的方法
310 0
|
6月前
Crypto-JS——Uncaught Error: Malformed UTF-8 data
Crypto-JS——Uncaught Error: Malformed UTF-8 data
432 0
|
9月前
|
JavaScript 算法
JS中如何对<input type=“data“>中值进行运算(JS日期类型如何进行加减)
JS中如何对<input type=“data“>中值进行运算(JS日期类型如何进行加减)
81 0
|
9月前
|
JavaScript
js知识总结 -- Math对象、data日期对象的方法及功能
js知识总结 -- Math对象、data日期对象的方法及功能
68 0
|
缓存 前端开发 JavaScript
一看就会的Next.js App Router版 -- Data Fetching(三)
一看就会的Next.js App Router版 -- Data Fetching
401 0
|
缓存 前端开发 数据库
一看就会的Next.js App Router版 -- Data Fetching(二)
一看就会的Next.js App Router版 -- Data Fetching
168 0
|
存储 缓存 前端开发
一看就会的Next.js App Router版 -- Data Fetching(一)
一看就会的Next.js App Router版 -- Data Fetching
605 0
|
JavaScript 前端开发
【Vue.js 入门与实战】--组件传值-父组件向子组件传值和data与props的区别
vm 实例也可以看成一个大的组件 ,因为也有自己的控制区域与 date。同时实例也可以看到是一个组件。
【Vue.js 入门与实战】--组件传值-父组件向子组件传值和data与props的区别

热门文章

最新文章

  • 1
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    24
  • 2
    Node.js 中实现多任务下载的并发控制策略
    32
  • 3
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    25
  • 4
    【JavaScript】深入理解 let、var 和 const
    48
  • 5
    【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
    44
  • 6
    【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
    53
  • 7
    【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
    55
  • 8
    如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
    71
  • 9
    【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
    55
  • 10
    JavaWeb JavaScript ③ JS的流程控制和函数
    62