Text 作为起点
Text 至 Blob
const blob = new Blob(["Hello, world!"], {
type: "text/plain"
});
console.log(blob)
Text 至 File
const file = new File(["Hello, world!"], "hello.txt", {
type: "text/plain"
});
console.log(file)
Text 至 URL
encodeURIComponent按照Unicode字符集将所有字符进行解码,再把每个字节从二进制转为十六进制表示,也就是两个16进制字符表示一个字节,最后在每个字节的前面加上%输出。
const arrayBuffer = new TextEncoder().encode(`我`)
const encodedStr = Array.from(arrayBuffer)
.map(i => Number(i).toString(16))
.map(i => i.toUpperCase())
.join("%")
console.log(encodedStr); // E6%88%91
encodeURIComponent(`我`) // %E6%88%91
encodeURIComponent 编码的字符范围比 encodeURI 更广,/、?、:等都可以进行编码。
encodeURIComponent(`http://www.baidu.com?name=我&age=18`)
// http%3A%2F%2Fwww.baidu.com%3Fname%3D%E6%88%91%26age%3D18
encodeURI(`http://www.baidu.com?name=我&age=18`)
// http://www.baidu.com?name=%E6%88%91&age=18
注意:
encodeURIComponent配合decodeURIComponent使用。encodeURI配合decodeURI使用。- 对URL进行转码时候,可以采用
encodeURIComponent,更加的全面。
Text 至 Base64
0-255以内的字符,属于 Latin1 字符集
const text = "Hello World";
console.log(window.btoa(text));
-
先把
"hello world!"按Latin1编码逐字符字节流。['01001000', '01100101', '01101100', '01101100', '01101111', '00100000', '01010111', '01101111', '01110010', '01101100', '01100100'] -
再把这串字节流按
Base64编码转成可打印文本。SGVsbG8gV29ybGQ=
注意:
btoa只支持Latin1编码的字符,对于 非Latin1编码的字符会抛出错误。
window.btoa("你好!")
包含中文、特殊字符等,属于 Unicode 字符集
encodeURIComponent
const text = "w爱n";
let encodedString = encodeURIComponent(text);
console.log(window.btoa(encodedString));
- 先通过
UTF-8编码转为 字节流。
[119, 231, 136, 177, 110]
- 将字节流转为 16 进制字符。
['77', 'e7', '88', 'b1', '6e']
- 字符通过用
%接成字符串。
77%E7%88%B1%6E
- 先把
77%E7%88%B1%6E按Latin1编码逐字符字节流。
['00110111', '00110111', '00100101', '01000101', '00110111', '00100101', '00111000', '00111000', '00100101', '01000010', '00110001', '00100101', '00110110', '01000101']
- 再把这串字节流按
Base64编码转成可打印文本。
NzclRTclODglQjElNkU=
TextEncoder 配合 fromCharCode
const text = "w爱n";
const encodedBuffer = new TextEncoder().encode(text)
let characters = [];
for (let i = 0; i < encodedBuffer.length; i++) {
characters.push(String.fromCharCode(encodedBuffer[i]));
}
const concatenatedString = characters.join('')
console.log(window.btoa(concatenatedString));
FileReader
const text = "w爱n";
const file = new File([text], "text.txt", { type: "text/plain" });
const render = new FileReader();
render.readAsDataURL(file);
render.onload = function () {
console.log(render.result);
}
Text 至 ArrayBuffer
方案一:只处理ASCII码表字符
/**
* 将字符串转换为字节缓冲(仅支持单字节 ASCII)
* 约束:
* - 每个字符的码点必须 <= 0xFF(单字节)
* - 若包含多字节字符(如中文、emoji),结果将错误或不可靠
* @param {string} str - 仅含单字节 ASCII 的字符串
* @return {ArrayBuffer} 字节缓冲
*/
function string2ArrayBuffer(str) {
let val = '';
for (let i = 0; i < str.length; i++) {
// 取当前字符的 UTF-16 码单元(0-65535),并转为十六进制字符串
if (val === '') {
val = str.charCodeAt(i).toString(16);
} else {
// 继续拼接下一个字符的十六进制表示,用逗号分隔
val += ',' + str.charCodeAt(i).toString(16);
}
}
// 将16进制转化为ArrayBuffer
// 通过正则匹配每两个十六进制字符(一个字节),再用 parseInt 转为 0-255 的数值
// 用这些数值构造 Uint8Array,并返回其底层的 ArrayBuffer
return new Uint8Array(
val.match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16);
})
).buffer;
}
console.log(string2ArrayBuffer('hello'));
方案二:TextEncoder转换(微信小程序不支持)
const encoder = new TextEncoder();
console.log(encoder.encode("我i你").buffer);
方案三:处理全部字符
/**
* 将字符串转换为 UTF-8 编码的 ArrayBuffer
* @param {string} str - 输入字符串
* @return {ArrayBuffer} 转换后的 ArrayBuffer
*/
function string2ArrayBuffer(str) {
let len = str.length;
let bytes = 0;
// 计算需要的字节数
for (let i = 0; i < len; i++) {
const code = str.charCodeAt(i);
if (code < 0x007F) {
bytes += 1;
} else if (code < 0x07FF) {
bytes += 2;
} else if (code < 0xFFFF) {
bytes += 3;
} else {
bytes += 4;
}
}
// 分配缓冲区
const buffer = new ArrayBuffer(bytes);
const uint8 = new Uint8Array(buffer);
let offset = 0;
// 填充字节
for (let i = 0; i < len; i++) {
const code = str.charCodeAt(i);
if (code < 0x007F) {
uint8[offset++] = code;
} else if (code < 0x07FF) {
uint8[offset++] = 0xC0 | (code >>> 6);
uint8[offset++] = 0x80 | (code & 0x3F);
} else if (code < 0xFFFF) {
uint8[offset++] = 0xE0 | (code >>> 12);
uint8[offset++] = 0x80 | ((code >>> 6) & 0x3F);
uint8[offset++] = 0x80 | (code & 0x3F);
} else {
uint8[offset++] = 0xF0 | (code >>> 18);
uint8[offset++] = 0x80 | ((code >>> 12) & 0x3F);
uint8[offset++] = 0x80 | ((code >>> 6) & 0x3F);
uint8[offset++] = 0x80 | (code & 0x3F);
}
}
return buffer;
}
console.log(string2ArrayBuffer('我i你'));
Blob作为起点
Blob 至 File
const blob = new Blob(["Hello, world!"], {
type: "text/plain"
});
const file = new File([blob], "hello.txt", {
type: "text/plain"
});
console.log(file)
Blob 至 Text
const blob = new Blob(["Hello, world!"], {
type: "text/plain"
});
const reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
};
reader.readAsText(blob);
Blob 至 Base64
const blob = new Blob(["Hello, world!"], {
type: "text/plain"
});
const reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
};
reader.readAsDataURL(blob);
Blob 至 ArrayBuffer
const blob = new Blob(["Hello, world!"], {
type: "text/plain"
});
const reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
};
reader.readAsArrayBuffer(blob);
Blob 至 ObjectURL
const blob = new Blob(["Hello, world!"], {
type: "text/plain"
});
const objectUrl = URL.createObjectURL(blob);
console.log(objectUrl);
File作为起点
File 至 Text
const file = new File(["Hello, world!"], "hello.txt", {
type: "text/plain"
});
const reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
};
reader.readAsText(file);
File 至 Base64
const file = new File(["Hello, world!"], "hello.txt", {
type: "text/plain"
});
const reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
};
reader.readAsDataURL(file);
File 至 ArrayBuffer
const file = new File(["Hello, world!"], "hello.txt", {
type: "text/plain"
});
const reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
};
reader.readAsArrayBuffer(file);
File 至 ObjectURL
const file = new File(["Hello, world!"], "hello.txt", {
type: "text/plain"
});
const objectUrl = URL.createObjectURL(file);
console.log(objectUrl);
ArrayBuffer 作为起点
ArrayBuffer 至 Base64
const buffer = new ArrayBuffer(8);
const uint8Array = new Uint8Array(buffer);
let binaryString = '';
for (let i = 0; i < uint8Array.length; i++) {
binaryString += String.fromCharCode(uint8Array[i]);
}
const base64String = btoa(binaryString);
console.log(base64String);
ArrayBuffer 至 Blob
const buffer = new ArrayBuffer(8);
const blob = new Blob([buffer], {
type: "text/plain"
});
console.log(blob)
ArrayBuffer 至 File
const buffer = new ArrayBuffer(8);
const file = new File([buffer], "file.txt", {
type: "text/plain",
});
console.log(file)
ArrayBuffer 至 Text
方案一:手动解析ArrayBuffer
const arrayBuffer = new TextEncoder().encode("我i你").buffer
/**
* 将字节数组转换为字符串(支持 UTF-8 多字节字符)
* @param {ArrayBuffer} bytes - 字节数组
* @returns {string} - 转换后的字符串
*/
function bytesToString(bytes) {
// 将字节数组解码为字符串(支持 UTF-8 多字节字符)
let result = '';
const input = new Uint8Array(bytes);
for (let i = 0; i < input.length; i++) {
// 将当前字节转为 8 位二进制字符串(不足位数时左侧补零)
const binary = input[i].toString(2).padStart(8, '0');
// 通过前导连续的 1(且后跟一个 0)判断是否为多字节字符的起始字节
// 例如:110xxxxx(2 字节)、1110xxxx(3 字节)、11110xxx(4 字节)
const leadingOnesMatch = binary.match(/^1+?(?=0)/);
if (leadingOnesMatch) {
// 多字节字符的总字节数由前导 1 的个数决定
const numBytes = leadingOnesMatch[0].length;
// 起始字节中的有效位(去掉前导位与紧随的 0)
// 对于 110xxxxx、1110xxxx、11110xxx 等,取后面的 x 位
let codeBits = binary.slice(7 - numBytes);
// 依次读取并拼接后续续字节(形如 10xxxxxx)的 6 个有效位
for (let offset = 1; offset < numBytes; offset++) {
codeBits += input[i + offset].toString(2).padStart(8, '0').slice(2);
}
// 将拼接得到的二进制位转换为码点,再转为字符
result += String.fromCharCode(parseInt(codeBits, 2));
// 跳过已处理的续字节
i += numBytes - 1;
} else {
// 单字节(ASCII)字符,直接转换
result += String.fromCharCode(input[i]);
}
}
// 返回最终拼接的字符串
return result;
};
console.log(bytesToString(arrayBuffer));
方案二:TextDecoder解析(微信小程序不支持)
const arrayBuffer = new TextEncoder().encode("我i你").buffer
const decoder = new TextDecoder();
const str = decoder.decode(arrayBuffer);
console.log(str);
Base64作为起点
Base64 至 ArrayBuffer
const base64String = "d+eIsW4=";
// 将Base64字符串解码为字符串,这里的编码是“Latin1”
const binaryString = window.atob(base64String);
// 将二进制字符串转换为Uint8Array,这里的编码是“UTF-8”
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// 输出ArrayBuffer
console.log(bytes.buffer);
Base64 至 Blob
const base64String = "SGVsbG8gd29ybGQh";
// 将Base64字符串解码为字符串,这里的编码是“Latin1”
const binaryString = window.atob(base64String);
// 将二进制字符串转换为Uint8Array,这里的编码是“UTF-8”
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// 创建Blob对象
const blob = new Blob([bytes], { type: "text/plain" });
console.log(bytes)
Base64 至 Text
0-255以内的字符,属于 Latin1 字符集
const base64String = "SGVsbG8gV29ybGQ=";
console.log(window.atob(base64String));
包含中文等...,属于 Unicode 字符集
const text = "dyVFNyU4OCVCMW4=";
let encodedString = decodeURIComponent(window.atob(text));
console.log(encodedString);
encodeURIComponent 要配合 encodeURIComponent 一同使用哦!!!
TextDecoder 配合 charCodeAt
const base64String = "d+eIsW4=";
const binaryString = window.atob(base64String);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
console.log(new TextDecoder().decode(bytes));
URL作为起点
URL 至 ArrayBuffer
const audioUrl = 'https://audio-1304256198.cos.ap-guangzhou.myqcloud.com/%E4%BA%B2%E5%88%87%E5%A5%B3%E5%A3%B0.mp3'
const response = await fetch(audioUrl)
const arrayBuffer = await response.arrayBuffer()