javascript中Data URI使用详解

Data URI,不是URL
URL是uniform resource locator的缩写,在web中的每一个可访问资源都有一个URL地址,例如图片,HTML文件,js文件以及style sheet文件,我们可以通过这个地址去download这个资源。

其实URL是URI的子集,URI是uniform resource identifier的缩写。URI是用于获取资源,包括其附加的信息的一种协议。附加信息可能是地址,也可能不是地址,如果是地址,那么这时URI就变成URL了。注意的是data URI不是URL,因为它并不包含资源的公共地址。

Data URI
Data URI 是由 RFC 2397 定义的一种把小文件直接嵌入文档的方案。基本的格式如下:

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

代码
其实整体可以视为三部分,即【声明】:【参数】+【数据】,逗号左边的是各种参数,右边的是数据。

声明:
data:是URI的协议头,表明其资源是一个data URI;

参数:
1:mime type,表示数据呈现的格式,即指定嵌入数据的MIME。对于PNG的图片,其格式是:image/png,如果没有指定,默认是:text/plain;

2:character set(字符集)大多数被省略,默认是:charset=US-ASCII。如果指定是的数据格式是图片时,字符集将不再使用;

3:base64,这一部分将表明其数据的编码方式,此处为声明后面的数据的编码是base64,我们可以不必使用base64编码格式,如果那样,我们将使用标准的URL编码方式(形如%XX%XX%XX的格式);

注:base64是一种编码方式,将数据变成位流(bit stream),然后将其映射到base64的集合内。
base64包含A-Z,a-z,自然数以及+,/符号。等号=表明我们需要进行位填充(padding)。

数据:
这个encoded data部分为实际的数据,可能包含空格,但是无关紧要。

例如:data:image/png;base64,iVBORw0KGgoAAAA…/5AhVEMnSs9MAAAAASUVORK5CYII=

代码
Data URI支持的类型有:
data:,文本数据
data:text/plain,文本数据
data:text/html,HTML代码
data:text/html;base64,base64编码的HTML代码
data:text/css,CSS代码
data:text/css;base64,base64编码的CSS代码
data:text/javascript,Javascript代码
data:text/javascript;base64,base64编码的Javascript代码
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据

所以,这就是为什么我开始要先说明是Data URI,不是URL;因为只有当附加信息为文件(图片,HTML文件,js文件以及style sheet文件)时,才可以将它理解为URL;而附加信息并非只可以为【文件】,也可以是【文本数据】;

例1:(文本数据)

data:text/plain;base64,bXkgbmFtZSBpcyBKaW9uZy4=

代码
data:text/plain;charset=utf-8;base64,5biV5ouT6YCK5Y+85Y+855qE
例2:(图片数据)

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA7ElEQVQ4Ed2TLY7DMBBGP/cEvYFpWY+wZT5CjhDoHqMscKHDCgO7LMsCCx2WFhm6rPCrnB81srOVumSljWRFtue9GY1tYUlu8MuvLbEKaFsKCPHeKNshaS+I80tdw7kaWsY76TwVKIOvww7r2wXtFYAysL5DlW9TOqyEHlgDAiBUwcaT965iLsc1mbFoHMk7uyrnNsQBNAPIp0B98hxgd6Ke4DE4AKpo2GtGeSLQlaOfZ57BfXUAZXak9Z5N8bFQwQIwgUv/qYKoiRq1J8gfhjVJIyPBsH/73if3Yjr32LAoiINezf+BQPz5a3wA3EDHM/SuNwwAAAAASUVORK5CYII=

优点
1:减少HTTP请求数,没有了TCP连接消耗和同一域名下浏览器的并发数限制。

2:对于小文件会降低带宽。虽然编码后数据量会增加,但是却减少了http头,当http头的数据量大于文件编码的增量,那么就会降低带宽。

3:对于HTTPS站点,HTTPS和HTTP混用会有安全提示,而HTTPS相对于HTTP来讲开销要大更多,所以Data URI在这方面的优势更明显。

4:可以把整个多媒体页面保存为一个文件。

5:当图片是在服务器端用程序动态生成,每个访问用户显示的都不同时

缺点
1:无法被重复利用,同一个文档应用多次同一个内容,则需要重复多次,数据量大量增加,增加了下载时间。

2:无法被独自缓存,所以其包含文档重新加载时,它也要重新加载。

3:客户端需要重新解码和显示,增加了点消耗。

4:不支持数据压缩,base64编码会增加1/3大小,而urlencode后数据量会增加更多。

5:不利于安全软件的过滤,同时也存在一定的安全隐患。

6:移动端不宜使用 Data URI 技术(解码耗 CPU)。

7:不利于维护

注:A:通过CSS样式文件使用Data URI。
B:使用gzip压缩后的最终数据量是(1 + 1/3) * 2 * (1/3) = 8/9,所以最终流量是减少的。

使用方式
1:嵌入文档使用,例如:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA7ElEQVQ4Ed2TLY7DMBBGP/cEvYFpWY+wZT5CjhDoHqMscKHDCgO7LMsCCx2WFhm6rPCrnB81srOVumSljWRFtue9GY1tYUlu8MuvLbEKaFsKCPHeKNshaS+I80tdw7kaWsY76TwVKIOvww7r2wXtFYAysL5DlW9TOqyEHlgDAiBUwcaT965iLsc1mbFoHMk7uyrnNsQBNAPIp0B98hxgd6Ke4DE4AKpo2GtGeSLQlaOfZ57BfXUAZXak9Z5N8bFQwQIwgUv/qYKoiRq1J8gfhjVJIyPBsH/73if3Yjr32LAoiINezf+BQPz5a3wA3EDHM/SuNwwAAAAASUVORK5CYII=">

代码
注:这种方法避免了一次HTTP请求,但却无法被浏览器缓存,每次使用时都需要重新加载一次!

2:通过CSS样式文件,例如:

.img_box { 
          width: 100px;
          height: 100px;
          border: 1px solid gray;
          padding: 10px;
          background-image:
          url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA7ElEQVQ4Ed2TLY7DMBBGP/cEvYFpWY+wZT5CjhDoHqMscKHDCgO7LMsCCx2WFhm6rPCrnB81srOVumSljWRFtue9GY1tYUlu8MuvLbEKaFsKCPHeKNshaS+I80tdw7kaWsY76TwVKIOvww7r2wXtFYAysL5DlW9TOqyEHlgDAiBUwcaT965iLsc1mbFoHMk7uyrnNsQBNAPIp0B98hxgd6Ke4DE4AKpo2GtGeSLQlaOfZ57BfXUAZXak9Z5N8bFQwQIwgUv/qYKoiRq1J8gfhjVJIyPBsH/73if3Yjr32LAoiINezf+BQPz5a3wA3EDHM/SuNwwAAAAASUVORK5CYII="); 
         }
1

注:这种方法避免了一次HTTP请求,还能同CSS文件一起被浏览器缓存起来,重复使用,不会每次使用时都加载一次。
浏览器支持情况
1) Firefox 2+

2) Opera 7.2+ – 数据URI不得超过4100个字符

3) Chrome(所有版本)

4) Safari(所有版本)

5) Internet Explorer 8+ – 数据URI必须小于32 k

性能的影响
Data URI最有兴趣的一点是它允许让你在文件中嵌入其他的文件。许多新手将图片嵌入在CSS文件中来作为一种提高性能的方式。实际上,有许多研究表明,HTTP请求是很多网站性能黑洞,能减少HTTP请求从某种意义上讲是可以提高性能的。“Minimize the HTTP request”也恰好是Yahoo的准则。

但是很多研究也表明,Data URI的滥用反而会适得其反:
1:base64下载速度较慢
2:base64在css下载完成前一直处于“白屏”状态
3:使用Data URI方式的Demo在渲染时会比不使用时多消耗53%左右的CPU资源,内存多出4倍左右,耗时平均高出24.6倍 。由此可见,使用Data URl方式还是需要更多的考量,在可接受的范围内适量使用。


参考:

Data URI&MHTML: 用还是不用?
移动端性能大比拼:CSS Sprites vs. Data URI
那么我们应该在什么情况下来使用Data URI呢?详见下文:

Data URI使用建议
1:建议开发者限制Data URI在较小资源上的使用,并且不要在CSS或内联HTML里多次使用。

2:能使用sprite的地方还是尽量使用sprite。

3:个别不方便使用sprite且质量小的图片可以使用data uri,比如 – 宽高不固定且又有要求background-position:center bottom。

4:repeat/repeat-x/repeat-y的图片。

5:对个别BT需求时可以用来做为替代img的方案。

base64在线生成工具
1:图片在线转换Base64

2:Data URI编码工具

3:Data URI Maker

时间: 2024-09-26 04:13:57

javascript中Data URI使用详解的相关文章

JavaScript中的Promise使用详解

  这篇文章主要介绍了JavaScript中的Promise使用详解,promise对象是JS进阶学习中的重要知识点,需要的朋友可以参考下 许多的语言,为了将异步模式处理得更像平常的顺序,都包含一种有趣的方案库,它们被称之为promises,deferreds,或者futures.JavaScript的promises ,可以促进关注点分离,以代替紧密耦合的接口. 本文讲的是基于Promises/A 标准的JavaScript promises.[http://wiki.commonjs.org

JavaScript中的依赖注入详解

 这篇文章主要介绍了JavaScript中的依赖注入详解,本文讲解了requirejs/AMD方法.反射(reflection)方法等内容,需要的朋友可以参考下     计算机编程的世界其实就是一个将简单的部分不断抽象,并将这些抽象组织起来的过程.JavaScript也不例外,在我们使用JavaScript编写应用时,我们是不是都会使用到别人编写的代码,例如一些著名的开源库或者框架.随着我们项目的增长,我们需要依赖的模块变得越来越多,这个时候,如何有效的组织这些模块就成了一个非常重要的问题.依赖

JavaScript中的继承方式详解

 这篇文章主要介绍了JavaScript中的继承方式详解,本文讲解了js继承的概念.原型式继承与类式继承.原型链继承.类式继承.组合继承.原型式继承等内容,需要的朋友可以参考下     js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念.所以,要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现 在面向对象的语言中,我们使用类来

JavaScript中的函数模式详解

 这篇文章主要介绍了JavaScript中的函数模式详解,本文讲解了创建函数的语法.函数表达式.命名函数表达式.函数的声明.函数声明与表达式.函数的提升.即时函数模式等内容,需要的朋友可以参考下     JavaScript设计模式的作用是提高代码的重用性,可读性,使代码更容易的维护和扩展 在javascript中,函数是一类对象,这表示他可以作为参数传递给其他函数:此外,函数还可以提供作用域. 创建函数的语法 命名函数表达式 代码如下: //命名函数表达式 var add = function

JavaScript中 ES6 generator数据类型详解_javascript技巧

1. generator简介 generator 是ES6引入的新的数据类型, 看上去像一个函数,除了使用return返回, yield可以返回多次. generator 由function* 定义, (注意*号), 2. 示例 函数无法保存状态, 有时需要全局变量来保存数字: 2.1 'use strict'; function next_id(){ var id = 1; while(id<100){ yield id; id++; } return id; } // 测试: var x,

javascript中Array()数组函数详解_javascript技巧

在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活.强大,不像是Java等强类型高级语言数组只能存放同一类型或其子类型元素,JavaScript在同一个数组中可以存放多种类型的元素,而且是长度也是可以动态调整的,可以随着数据增加或减少自动对数组长度做更改. Array()是一个用来构建数组的内建构造器函数.数组主要由如下三种创建方式: array = new Array() array =

JavaScript中eval()函数用法详解_javascript技巧

eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行. 如果参数是一个表达式,eval() 函数将执行表达式.如果参数是Javascript语句,eval()将执行 Javascript 语句. 语法 复制代码 代码如下: eval(string) 参数 描述 string 必需.要计算的字符串,其中含有要计算的 JavaScript 表达式或要执行的语句. eval()函数用法详解: 此函数可能使用的频率并不是太高,但是在某些情况下具有很大的作用,下面就介绍一下eva

JavaScript中的Promise使用详解_基础知识

许多的语言,为了将异步模式处理得更像平常的顺序,都包含一种有趣的方案库,它们被称之为promises,deferreds,或者futures.JavaScript的promises ,可以促进关注点分离,以代替紧密耦合的接口. 本文讲的是基于Promises/A 标准的JavaScript promises.[http://wiki.commonjs.org/wiki/Promises/A] Promise的用例:     执行规则     多个远程验证     超时处理     远程数据请求

javascript中的正则表达式使用详解_javascript技巧

[1]定义:正则又叫规则或模式,是一个强大的字符串匹配工具,在javascript中是一个对象 [2]特性: [2.1]贪婪性,匹配最长的 [2.2]懒惰性,不设置/g,则只匹配第1个 [3]两种写法: [3.1]perl写法(使用字面量形式): var expression = /pattern/flags; e.g. var pattern = /a/i;//匹配字符串中所有'a'的实例 [3.1.1]三个标志flags [a]g:表示全局模式(global) [b]i:表示不区分大小写(i