Data URL各字符的含义
网页上有些图片的src或css背景图片的url后面跟了一大串字符,比如:
<pre style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">.title {
background-image:url(data:image/gif;base64,R0lGODlhAQAcALMAAMXh96HR97XZ98Hf98Xg97DX97nb98Lf97vc98Tg973d96rU97ba97%2Fe96XS9wAAACH5BAAAAAAALAAAAAABABwAAAQVMLhVBDNItXESAURyDI2CGIxQLE4EADs%3D);
background-repeat:repeat-x;
height:28px;
line-height: 28px;
text-align:center;
}</pre>
其中background-image:url后面跟了一堆字符,这就是Data URI scheme。将url后面的输入到地址栏,会发现是一个竖线的图片。
data
表示取得数据的协定名称
image/png
是数据类型名称,
base64
是数据的编码方法,
逗号后面
就是这个image/png文件base64编码后的数据。
Data URI scheme支持的类型有:图片
、css样式
、JavaScript
等等。
因为Url是一种基于文本的协议,所以gif/png/jpeg这种二进制属于需要用base64进行编码。
换句话说,引入base64以后,就可以支持任意形式的数据格式。
Data URL优缺点
Data URI scheme 允许我们使用内联(inline-code)的方式在网页中包含数据,目的是将一些小的数据,直接嵌入到网页中,从而不用再从外部文件载入。常用于将图片嵌入网页。
平常我们加载网页过程中,会发现图片加载很慢,很卡,这就是因为网页加载到浏览器中时,浏览器会针对每个外部资源都向服务器发送一次拉取资源请求,占用网络资源。
大多数的浏览器都有一个并发请求数不能超过4个的限制。这意味着,如果一个网页里嵌入了过多的外部资源,这些请求会导致整个页面的加载延迟。
优点:
Url原本会引起一个新的网络访问,但是现在Data URL可以把数据类型直接嵌入到当前页面中,这样文件就可以直接从页面文件内部直接读入,而不需要通过向服务器发送Http请求再返回外部文件,从而减少服务器负载,页面加载的速度也会更快。
- 当访问外部资源很麻烦或受限时
- 当图片是在服务器端用程序动态生成,每个访问用户显示的都不同时。
- 当图片的体积太小,占用一个HTTP会话不是很值得时。
缺点:
因为这种方式把数据加载到当前页面中,也会增加当前文件的大小,所以这种情况更适用于特别“小的数据”。
- Base64编码的数据体积通常是原数据的体积4/3,也就是Data URL形式的图片会比二进制格式的图片体积大1/3。
- Data URL形式的图片不会被浏览器缓存,这意味着每次访问这样页面时都被下载一次。这是一个使用效率方面的问题——尤其当这个图片被整个网站大量使用的时候。
另外浏览器不会缓存这种图像
简单说:Data:后面的数据直接用做网页的内容,而不是网页的地址。
浏览器兼容性
所谓"Data"类型的Url格式,早在1998年就在RFC2397中提出了,时至今日,Firfox、Opera、Safari和Konqueror这些浏览器都已经支持,但是IE直到7.0版本都还没有支持,IE不支持的东西太多了,也不差这一个。:(
在CSS里使用Data URL
当第一次看到Data URL的作用和用法时,你也许会很不疑惑,“为什么要麻烦的将图片转换成base64编码字符串,还要嵌入的网页中,将HTML代码弄的混乱不堪,甚至还会有性能上的问题。”
诚然,无法否认缓存在浏览器性能中的重要作用——如何能将Data URL数据也放入浏览器缓存中呢?
答案是:通过CSS样式文件。
CSS中的url操作符是用来指定网页元素的背景图片的,而浏览器并不在意URL里写的是什么——只要能通过它获取需要的数据。所以,我们就有了可以将Data URL形式的图片存储在CSS样式表中的可能。而所有浏览器都会积极的缓存CSS文件来提高页面加载效率。
假设我们的页面里有一个很小的div元素,我们想用一种灰色的斜纹图案做它的背景,这种背景在当今的网站设计者中非常流行。传统的方法是制作一个3×3像素的图片,保存成GIF或PNG格式,然后在CSS的background-image属性中引用它的地址。而Data URL则是一种更高效的替代方法,就像下面这样。
<pre style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">.box {
width: 100vw;
height: 100vh;
background-image:url(data:image/gif;base64,R0lGODlhAwADAIAAAP///8zMzCH5BAAAAAAALAAAAAADAAMAAAIEBHIJBQA7);
background-repeat:repeat-x;
padding: 40px;
text-align:center;
}
<div clss="box">
这是一个条纹的背景
</div></pre>
在这个例子中,Data URL的使用是完全符合场景的。它避免了让这个小小的背景图片独自产生一次HTTP请求,而且,这个小图片还能同CSS文件一起被浏览器缓存起来,重复使用,不会每次使用时都加载一次。只要这个图片不是很大,而且不是在CSS文件里反复使用,就可以以Data URL方法呈现图片降低页面的加载时间,改善用户的浏览体验。
如何把数据转换成Data URL的格式
base64简单地说,它把一些 8-bit 数据翻译成标准 ASCII 字符,网上有很多免费的base64 编码和解码的工具。
其中一个是在线工具,一个Mac OS X桌面应用。
- DataURLMaker在线工具
- DataURLMaker Mac OS X 桌面
在PHP中可以用函数base64_encode() 进行编码,如:
<pre style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">echo base64_encode(file_get_contents(‘wg.png’));</pre>
当然也可以用base64decode()用于解码。
Data类型的URL格式和类型
语法
[property]:url( data:[ mediatype ] [ ;base64] ,data)
<pre style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">.box{
background-image:url(data:image/gif;base64,R0lGODlhAwADAIAAAP///8zMzCH5BAAAAAAALAAAAAADAAMAAAIEBHIJBQA7);
}</pre>
用来帮助理解,具体看规范
mediatype: [ type "/" subtype ] ( ";" parameter )
data: urlchar
parameter : attribute "=" value
urlchar指的就是一般url中允许的字符,有些字符需要转义,例如有些在线转换把base64里面的“=”转换成为%3D,这个在Url中和“=”是一样的,不转换也没什么问题。
parameter可以对mediatype进行属性的扩展,常见的是charset,用来定义编码格式,在多语言情况下需要用到。例如下面的例子。
<pre style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">data:text/plain;charset=UTF-8;base64,5L2g5aW977yM5Lit5paH77yB</pre>
这个例子会显示出"你好,中文!"。如果吧charset部分去掉,就会显示乱码,因为我用的是UTF-8编码。
Firefox有一个data类型Url的测试页面,列出了各种格式的data类型Url的测试Url,和测试结果说明。
<pre style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">###Data URI的格式规范
data:[<mediatype type>][;charset=<charset>][;<encoding>],<encoded data>
各属性代表的含义:
1.data :协议名称;
- [<mediatype type>] : 可选项,数据类型type/subtype(image/png、text/plain等)
- [;charset=<charset>] :可选项,源文本的字符集编码方式
- [;<encoding>] :数据编码方式(默认US-ASCII,BASE64两种)
- ,<encoded data> :编码后的数据,注意数据前是逗号,其它都是分号。
Data URI scheme支持的类型
- 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图片数据</pre>
示例一:
我们直接在地址栏输入以下代码,页面会直接显示Hello,world!的文字。
<pre style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">data:text/html,<html><body><p><b>Hello, world!</b></p></body></html></pre>
[图片上传失败...(image-2bd975-1666368441539)]
示例二:
下面这个html代码可以在支持data类型Url的浏览器中运行,例如Firefox。运行后会看到一条蓝色渐变底色的标题。
<pre style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"><style type="text/css">
.title {
background-image:url(data:image/gif;base64,R0lGODlhAQAcALMAAMXh96HR97XZ98Hf98Xg97DX97nb98Lf97vc98Tg973d96rU97ba97%2Fe96XS9wAAACH5BAAAAAAALAAAAAABABwAAAQVMLhVBDNItXESAURyDI2CGIxQLE4EADs%3D);
background-repeat:repeat-x;
height:28px;
line-height: 28px;
text-align:center;
}
</style>
</head>
<body>
<div class="title">Hello, world!</div>
</body>
</html></pre>
什么是Base64
所谓Base64,就是说选出64个字符—-小写字母a-z、大写字母A-Z、数字0-9、符号”+”、”/”(再加上作为垫字的”=”,实际上是65个字符)—-作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。
具体来说,转换方式可以分为四步。
第一步,将每三个字节作为一组,一共是24个二进制位。
第二步,将这24个二进制位分为四组,每个组有6个二进制位。
第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。
第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w
15 P 32 g 49 x
16 Q 33 h 50 y
因为,Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右。
想要更多了解的可以看下这篇文章,或者网上自行查看,有不错的欢迎的留言在评论区,互相学习交流。
网友评论