CSS系列 - base64 编码

220 阅读2分钟

Data URL

Data URL,即前缀为 data: 协议的 URL,其允许内容创建者向文档中嵌入小文件 Data URL 由四个部分组成:前缀(data:)、指示数据类型的 MIME 类型、如果非文本则为可选的 base64 标记、数据本身。

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

Base64

Base64 是一组相似的二进制到文本(binary-to-text)的编码规则,使得二进制数据在解释成 radix-64 的表现形式后能够用 ASCII 字符串的格式表示出来。Base64 这个词出自一种特定的 MIME 内容传输编码

解码和编码 Base64 字符串

  • btoa():从二进制数据“字符串”创建一个 Base-64 编码的 ASCII 字符串(“btoa”应读作“binary to ASCII”)
  • atob():解码通过 Base-64 编码的字符串数据(“atob”应读作“ASCII to binary”)

FileReader.readAsDataURL()

readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend 事件,同时 result 属性将包含一个data:URL 格式的字符串(base64 编码)以表示所读取文件的内容。

传输 8Bit 字节代码的编码方式

优点

  • 减少了 HTTP 请求
  • 某些文件可以避免跨域的问题
  • 没有图片更新要重新上传
  • 清理缓存的问题

缺点

  • 增加了 CSS 文件的尺寸

    每一个 Base64 字符实际上代表着 6 比特位。因此,3 字节(一字节是 8 比特,3 字节也就是 24 比特)的字符串/二进制文件可以转换成 4 个 Base64 字符(4 x 6 = 24 比特)。

    这意味着 Base64 格式的字符串或文件的尺寸约是原始尺寸的 133%(增加了大约 33%)

  • 转换成本

  • Unicode 问题

    由于 JavaScript 字符串是 16 位编码的字符串,在大多数浏览器中,在 Unicode 字符串上调用 window.btoa,如果一个字符超过了 8 位 ASCII 编码字符的范围,就会引起 Character Out Of Range 异常。

    • 先对整个字符串转义,然后进行编码;
    function b64EncodeUnicode(str) {
      return btoa(encodeURIComponent(str));
    }
    
    function UnicodeDecodeB64(str) {
      return decodeURIComponent(atob(str));
    }
    
    b64EncodeUnicode("✓ à la mode"); // "JUUyJTlDJTkzJTIwJUMzJUEwJTIwbGElMjBtb2Rl"
    UnicodeDecodeB64("JUUyJTlDJTkzJTIwJUMzJUEwJTIwbGElMjBtb2Rl"); // "✓ à la mode"
    
    • 将 UTF-16 字符串转换为 UTF-8 字符数组,然后进行编码。

图片、字体

  • 不能与其他图片以 CSS Sprite 的形式存在,只能独行
  • 不会经常修改
  • 实际尺寸很小
  • 图片在网站中大规模使用
  • 可像单独图片一样使用,比如背景图片重复使用等
  • 没有跨域问题,无需考虑缓存、文件头或者cookies问题

CssSprites

  • 换肤切换功能
  • 不会经常修改(例如button大小、颜色等)
  • 使用时无需重复图形内容
  • 不会增加 CSS 文件体积
  • 降低图片更新的维护难度