JS 可否使用字符串传输文件?
在一个场景中,数据只能通过字符串传输,需要传文件或二进制对象时就比较麻烦。目前使用将文件编码为base64传输,但是这种方式会时传输的数据增大(50K的文件编码后为80K)。测试使用浏览器的TextDecoder
将文件编码为iso-8859-1,可以保持编码后字符串的大小和原文件一样,但是再转回文件时就转不回来了(TextEncoder
只支持utf-8)编码:
new TextDecoder('iso8859-1').decode(file);
====更新=====现通过以下方式解码,但是zip压缩包会出现乱码
let buffer = new ArrayBuffer(textData.length);
let arr = new Uint8Array(buffer);
for(let i = 0; i < textData.length; i++){
arr[i] = textData.charCodeAt(i);
}
请问是否还有其他方式可以实现?
回复
1个回答
test
2024-06-27
用Blob对象:
function stringToBlob(str, contentType) {
return new Blob([new Uint8Array([...str].map(ch => ch.charCodeAt(0)))], { type: contentType });
}
const blob = stringToBlob(textData, 'application/zip');
const url = URL.createObjectURL(blob);
用ArrayBuffer和DataView来控制二进制数据的读写:
function stringToArrayBuffer(str) {
const buffer = new ArrayBuffer(str.length);
const view = new DataView(buffer);
for (let i = 0; i < str.length; i++) {
view.setUint8(i, str.charCodeAt(i));
}
return buffer;
}
const buffer = stringToArrayBuffer(textData);
修复ISO-8859-1编码:
function encodeIso8859_1(arrayBuffer) {
const uint8Array = new Uint8Array(arrayBuffer);
return String.fromCharCode(...uint8Array);
}
function decodeIso8859_1(str) {
const uint8Array = new Uint8Array(str.length);
for (let i = 0; i < str.length; i++) {
uint8Array[i] = str.charCodeAt(i);
}
return uint8Array.buffer;
}
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容