data URIs

data URIs是由RFC 2397定义, 允许将一个小文件进行编码后嵌入到另外一个文档里.

语法

data URIs 的语法结构如下:

data:[<mediatype>][;base64],<data>

mediatype是一种MIME类型字符串, 例如 "image/jpeg" 代表 JPEG 图像文件.如果省略这个参数, 则默认值为text/plain;charset=US-ASCII

如果数据是文本类型, 你可以直接将文本嵌入在data:后面 (根据文本类型以及编码,使用合适的HTML实体编码或者百分号编码). 如果是二进制数据, 你可以将数据进行base64编码之后再进行嵌入.

下面是一些示例:

data:,Hello%2C%20World!
简单的text/plain类型数据
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
base64编码过的数据
data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E
一个HTML文档源代码 <h1>Hello, World</h1>

将数据进行base64编码

在Linux或者Mac OS系统上,你可以使用命令行程序uuencode:

uuencode -m infile remotename

输出结果如下,第一行文件头以下的数据就是组成 data URI 的base64编码.

begin-base64 664 test
YSBzbGlnaHRseSBsb25nZXIgdGVzdCBmb3IgdGV2ZXIK
====

你也可以使用在线网站 data URI kitchen, 来把一个字符串或文件转换成data URI.

将一个 nsIFile 转换为 data URI

下面的函数将一个nsIFile转换成为base64编码过的data URI .

function generateDataURI(file) {
  var contentType = Components.classes["@mozilla.org/mime;1"]
                              .getService(Components.interfaces.nsIMIMEService)
                              .getTypeFromFile(file);
  var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                              .createInstance(Components.interfaces.nsIFileInputStream);
  inputStream.init(file, 0x01, 0600, 0);
  var stream = Components.classes["@mozilla.org/binaryinputstream;1"]
                         .createInstance(Components.interfaces.nsIBinaryInputStream);
  stream.setInputStream(inputStream);
  var encoded = btoa(stream.readBytes(stream.available()));
  return "data:" + contentType + ";base64," + encoded;
}

安全性

Gecko 6.0 note
(Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3)

在Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3)之前, 如果用户在地址栏输入一个data URI并执行跳转,这个data URI会继承浏览器当前页面的安全上下文.6.0之后,data URIs只会在一个新的空的安全上下文上工作.

常见问题

下文介绍一些在使用data URIs时遇到的常见问题:

语法
data URIs 的格式很简单, 但很容易会忘记了在"data:"协议名后面必须有一个逗号(MIME类型和"base64"都是可省略的), 或者在对数据进行base64编码时发生错误.
HTML代码格式化
一个data URI 是作为了一个文件内的文件, 所以在嵌入其他文档的内部时,这个data URI 所在的行就会非常的长, 所以应当用空白符(换行符, 制表符, 空格)来对它进行格式化, 但如果数据是经过base64编码过的,就可能会遇到一些问题.
长度限制
虽然Mozilla支持无限长度的data URIs,但是标准中并没有规定浏览器必须支持无限长度的data URIs.比如,Opera 11限制data URIs的长度最多为65000个字符. 
缺乏错误处理
MIME类型错误或者base64编码错误,都会造成data URIs无法被正常解析, 但不会有任何相关错误提示.
不支持查询字符串

一个data URI的数据字段是没有结束标记的,所以尝试在一个data URI后面添加查询字符串会导致,查询字符串也一并被当作数据字段.例如:

data:text/html,lots of text...<p><a name%3D"bottom">bottom</a>?arg=val

这个data URI代表的HTML源文件内容为:

lots of text...<p><a name="bottom">bottom</a>?arg=val

注意: 从Firefox 6开始, data URI中的锚点标记(#)会像在其他普通网页url上一样可被识别,因此,如果想要表示文件内容中的 "#",必须将它转义为'%23'.

浏览器兼容性

已经支持data:协议的浏览器有Opera 7.20及其以上版本,Safari 和 Konqueror. Internet Explorer 7 及以下版本不支持, Internet Explorer 8 及以上版本只支持在css文件中使用data URIs格式的图片.

相关链接

文档标签和贡献者

 此页面的贡献者: ziyunfei
 最后编辑者: ziyunfei,