问题来源描述:
前端修改了头像,后面查询回的头像数据为二进制流。
返回的数据不能直接用做路径,需要转换数据格式为base64。
解决办法:
请求中设置responseType: "arraybuffer"
处理返回的结果如下:
let url = '';
if (res && res.data) {
let r = btoa(
new Uint8Array(res.data).reduce((d, byte) => d + String.fromCharCode(byte), '')
)
url = 'data:image/png;base64,' + r;
}
复制代码
处理后的结果:
扩展知识:
1. btoa
btoa(stringToEncode) 从 String 对象中创建一个 base-64 编码的 ASCII 字符串,其中字符串中的每个字符都被视为一个二进制数据字节。stringToEncode:一个字符串, 其字符分别表示要编码为 ASCII 的二进制数据的单个字节。返回一个包含 stringToEncode 的 Base64 表示的字符串。
let encodedData = window.btoa("This is a test string."); // 编码
let decodedData = window.atob(encodedData); // 解码
复制代码
注意:由于这个函数将每个字符视为二进制数据的字节,而不管实际组成字符的字节数是多少,所以如果任何字符的码位超出 0x00 ~ 0xFF 这个范围,则会引发 InvalidCharacterError 异常。可以使用此方法对可能导致通信问题的数据进行编码,传输,然后使用 atob() 方法再次解码数据。在多数浏览器中,使用 btoa() 对 Unicode 字符串进行编码都会触发 InvalidCharacterError 异常。一种选择是转义任何扩展字符,以便实际编码的字符串是原始字符的 ASCII 表示形式。
function utoa(str) {
return window.btoa(unescape(encodeURIComponent(str)));
}
// base64 encoded ascii to ucs-2 string
function atou(str) {
return decodeURIComponent(escape(window.atob(str)));
}
// Usage:
utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"
复制代码
2. Uint8Array
Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。
语法格式:
new Uint8Array(); // ES2017 最新语法
new Uint8Array(length); // 创建初始化为0的,包含length个元素的无符号整型数组
new Uint8Array(typedArray);
new Uint8Array(object);
new Uint8Array(buffer [, byteOffset [, length]]);
复制代码
使用例子:
// 来自长度
var uint8 = new Uint8Array(2);
uint8[0] = 42;
console.log(uint8[0]); // 42
console.log(uint8.length); // 2
console.log(uint8.BYTES_PER_ELEMENT); // 数组中元素的字节数 1
// 来自数组
var arr = new Uint8Array([21,31]);
console.log(arr[1]); // 31
// 来自另一个 TypedArray
var x = new Uint8Array([21, 31]);
var y = new Uint8Array(x);
console.log(y[0]); // 21
// 来自 ArrayBuffer
var buffer = new ArrayBuffer(8);
var z = new Uint8Array(buffer, 1, 4);
// 来自一个迭代器
var iterable = function*(){ yield* [1,2,3]; }();
var uint8 = new Uint8Array(iterable);
// Uint8Array[1, 2, 3]
复制代码
3. String.fromCharCode
静态方法 String.fromCharCode() 方法返回由指定的 UTF-16 代码单元序列创建的字符串。
语法:
String.fromCharCode(num1[, ...[, numN]])
参数:
num1, …, numN
一系列 UTF-16 代码单元的数字。范围介于 0 到 65535(0xFFFF)之间。大于 0xFFFF 的数字将被截断。不进行有效性检查。
返回值:
一个长度为 N 的字符串,由 N 个指定的 UTF-16 代码单元组成。
使用例子:
String.fromCharCode(65, 66, 67); // 返回 "ABC"
String.fromCharCode(0x2014); // 返回 "—"
String.fromCharCode(0x12014); // 也是返回 "—"; 数字 1 被剔除并忽略
String.fromCharCode(8212); // 也是返回 "—"; 8212 是 0x2014 的十进制表示
// 在 UTF-16 中,补充字符需要两个代码单元(即一个代理对):
String.fromCharCode(0xD83C, 0xDF03); // Code Point U+1F303 "Night with
String.fromCharCode(55356, 57091); // Stars" == "\uD83C\uDF03"
String.fromCharCode(0xD834, 0xDF06, 0x61, 0xD834, 0xDF07); // "\uD834\uDF06a\uD834\uDF07**"**
复制代码