[英]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.