[英]Convert binary data to base64 does not work with btoa unescape
我是 React 的新手,想显示下载为二进制数据的图像。 我从 api 调用 adobe lightroom api 下载图像数据。api 调用有效,因为图像在 Postman 中显示没有问题。 我还可以将图像数据保存到 jpeg 文件中,并且可以正常显示。
在 React 中,我想做<img src={`data:image/jpeg;base64,${theImage}`} />
为了让它工作,我需要将二进制数据转换为 base64 编码的字符串。 当我使用cat image.jpeg|base64 > base64.txt
转换下载的 jpeg 时,生成的字符串在我的 React 应用程序中有效。
但是当我在 React 中尝试var theImage = btoa(binarydata)
时,我得到Unhandled Rejection (InvalidCharacterError): Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
搜索问题后,我尝试使用var theImage = btoa(unescape(encodeURIComponent( binarydata )))
和类似的建议解决方案,但从中得到的字符串并不是 jpeg 的有效 base64 编码,因为它看起来(我尝试了结果来自在线 base64-> 图像服务中的转换,没有显示图像)。 我还尝试了其他建议的解决方案,例如base64-js和js-base64库,但没有一个创建有效的 base64 有效图像,可以在我的 React 代码中显示。
当btoa
抛出 latin1 异常时,如何将 jpeg 二进制数据转换为有效的 Base64 图像编码?
你说过你正在使用axios.get
从服务器获取图像。 您可能会返回Buffer
或ArrayBuffer
或Blob
等,但这取决于您如何处理从axios
获得的响应。
我不使用axios
(从未觉得有必要),但您可以通过fetch
从服务器轻松获取二进制数据的data
URI:
// 1.
const response = await fetch("/path/to/resource");
// 2.
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
// 3.
const buffer = await response.arrayBuffer();
// 4.
const byteArray = new Uint8Array(buffer);
// 5.
const charArray = Array.from(byteArray, byte => String.fromCharCode(byte));
// 6.
const binaryString = charArray.join("");
// 7.
const theImage = btoa(binaryString);
或者更简洁:
const response = await fetch("/path/to/resource");
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
const buffer = await response.arrayBuffer();
const binaryString = Array.from(new Uint8Array(buffer), byte => String.fromCharCode(byte)).join("");
const theImage = btoa(binaryString);
这是它的工作原理:
fetch
仅拒绝其 promise网络错误,而不是 HTTP 错误;这些通过status
和ok
道具报告。ArrayBuffer
; 缓冲区将包含二进制图像数据。Uint8Array
(使用该缓冲区)来访问它们。Array.from
和它的映射 function(为每个字节调用)来做到这一点,我们将使用String.fromCharCode
将字节转换为字符。 (这并不是真正的转换。字节 25 [例如] 变成字符串中字符代码为 25 的字符。) 查看文档,看起来axios
让您提供选项responseType: "arraybuffer"
来获取数组缓冲区。 如果我没看错,你可以像这样使用axios
:
const response = await axios.get("/path/to/resource", {responseType: "arraybuffer"});
const binaryString = Array.from(new Uint8Array(response.body), v => String.fromCharCode(v)).join("");
const theImage = btoa(binaryString);
将图像作为Blob获取并从中生成blob:// URI 。
data:// URLs是完全低效的,需要比 blob:// URLs 多得多的 memory 空间。 data:// URL比它代表的实际数据多占用 34% 的空间,它必须存储在 DOM 中 + 再次解码为二进制文件才能被图像解码器读取。 另一方面, blob:// URI只是指向 memory 中二进制数据的指针。
blob:// URL并不完美,但在浏览器正确实现srcDoc
之前,它仍然是我们拥有的最好的。
因此,如果根据您在浏览器中使用 axios 的评论,您可以这样做
const blob = await axios.get("/path/to/resource", {responseType: "blob"});
const theImage = URL.createObjectURL(blob);
如果你想使用fetch API
const response = await fetch("/path/to/resource");
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
const blob = await response.blob();
const theImage = URL.createObjectURL(blob);
附:
如果您没有任何特殊原因通过 AJAX 获取此图像(例如凭据或特殊的 POST 参数),则直接将资源的 URL 作为图像的src
传递:
<img src="/path/to/resource" />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.