前端根据后端数据生成可显示图像是一个比较常见的功能,比如验证码,动态海报。
后端传数据到前端,前端解析成校可视化验数据。
解析过程:指定数据类型 → 根据相关协议显示。
解析包括两个维度:
1.类型
解析后台数据,首先需要确定,返回数据类型,一般返回类型有 blob, arraybuffer。
2.协议
可视化展示需要指定协议,常用协议有 blob: ,data。
diff xhr.responseType + diff protocol
1.responseType: blob
1.1 URL.createObjectURL(blob);
1 | verificationCode().then(async blob => { |
Object URL 是一种伪协议,也被称为 Blob URL。它允许 Blob 或 File 对象用作图像,下载二进制数据链接等的 URL 源。在浏览器中,我们使用 URL.createObjectURL 方法来创建 Blob URL,该方法接收一个 Blob 对象,并为其创建一个唯一的 URL,其形式为 blob:
1 | blob:https://example.org/40a5fb5a-d56d-4a33-b4e2-0acf6a8e5f641 |
浏览器内部为每个通过 URL.createObjectURL 生成的 URL 存储了一个 URL → Blob 映射。因此,此类 URL 较短,但可以访问 Blob。生成的 URL 仅在当前文档打开的状态下才有效。但如果你访问的 Blob URL 不再存在,则会从浏览器中收到 404 错误。
缺点:虽然存储了 URL → Blob 的映射,但 Blob 本身仍驻留在内存中,浏览器无法释放它。映射在文档卸载时自动清除,因此 Blob 对象随后被释放。但是,如果应用程序寿命很长,那不会很快发生。因此,如果我们创建一个 Blob URL,即使不再需要该 Blob,它也会存在内存中。
针对这个问题,我们可以调用 URL.revokeObjectURL(url) 方法,从内部映射中删除引用,从而允许删除 Blob(如果没有其他引用),并释放内存。
1.2 blob协议转data协议
1 | const blobToBase64 = (blob) => { |
base64是 Data URI协议的一种实现,在1998年被确定,具体Data URI详细介绍。
1.3 blob 转 arraybuffer 转 data
1 | verificationCode().then(async blob => { |
2.responseType: arraybuffer
2.1 arraybuffer 转 base64
1 | verificationCode().then(blob => { |
额外知识点
arraybuffer转Blob
1 | var buffer = new ArrayBuffer(16); |
blob转arraybuffer
借助FileReader对象
1 | var blob = new Blob([1,2,3,4,5]); |
File FileList FileReader关系:
FileReader只能读取 File或者 blob对象,File对象是FileList的子集.
http 如何指定xhr.response的数据类型
有些时候我们希望xhr.response返回的就是我们想要的数据类型。比如:响应返回的数据是纯JSON字符串,但我们期望最终通过xhr.response拿到的直接就是一个 js 对象,我们该怎么实现呢?
有2种方法可以实现,一个是level 1就提供的overrideMimeType()方法,另一个是level 2才提供的xhr.responseType属性。
xhr.overrideMimeType()
overrideMimeType是xhr level 1就有的方法
如果服务器没有指定一个[Content-Type]
头, XMLHttpRequest
默认MIME类型为"text/xml"
. 如果接受的数据不是有效的XML,将会出现格”格式不正确“的错误。你能够通过调用 overrideMimeType()
指定各种类型来避免这种情况。
1 | // Interpret the received data as plain text |
再举一个使用场景,我们都知道xhr level 1不支持直接传输blob二进制数据,那如果真要传输 blob 该怎么办呢?当时就是利用overrideMimeType方法来解决这个问题的。
下面是一个获取图片文件的代码示例:
1 | var xhr = new XMLHttpRequest(); |
代码示例中xhr请求的是一张图片,通过将 response 的 content-type 改为’text/plain; charset=x-user-defined’,使得 xhr 以纯文本格式来解析接收到的blob 数据,最终用户通过this.responseText拿到的就是图片文件对应的二进制字符串,最后再将其转换为 blob 数据。
xhr.responseType
下面是同样是获取一张图片的代码示例,相比xhr.overrideMimeType,用xhr.response来实现简单得多。
1 | var xhr = new XMLHttpRequest(); |
简单来说,responseType就是把文本转换成 二进制了,二进制和文本怎么转换呢,请看下文分解
参考资源
玩转前端二进制
前端二进制学习
你真的会使用XMLHttpRequest吗
JS字符串与二进制的相互转化实例代码详解
玩转图片流Base64编码原理与应用
Data URI详细介绍
细说 Data URI