NodeJS中Buffer與字符串相互轉換時一個值得注意的問題


什么問題

如果一個Buffer的 toString() 結果為亂碼或含有亂碼,那么用此字符串以 Buffer.from()方法構造出來的Buffer將與原來的Buffer不相同。
這一點其實很好理解,只是很多和我一樣的初學者在使用時可能並不會意識到這一點。
用代碼演示的話如下:

let buf = Buffer.from([0x5a,0x6b,0x8c,0x7d,0x9e]);
console.log(buf.toString());
console.log(buf);
let buf1 = Buffer.from(buf.toString());
console.log(buf1);
console.log(buf1.equals(buf));
//運行結果如下

/*
Zk�}�
<Buffer 5a 6b 8c 7d 9e>
<Buffer 5a 6b ef bf bd 7d ef bf bd>
false
*/

怎樣解決

buf.toString()方法可傳入一個指示編碼格式的參數(參考NodeJS文檔),如果可以通過設置編碼格式使得toString()方法不發生亂碼則這個問題迎刃而解。其默認值為utf-8.
但是多數情況下我們並不能找到一種合適的編碼格式,比如當buf是來自一個圖片的二進制數據時,所以最好的方法還是盡量避免這種操作...

補充

Node.js 當前支持的字符編碼如下:

  • 'utf8': 多字節編碼的 Unicode 字符。 許多網頁和其他文檔格式都使用 UTF-8。 這是默認的字符編碼。 當將 Buffer 解碼為不專門包含有效 UTF-8 數據的字符串時,則會使用 Unicode 替換字符 U+FFFD � 來表示這些錯誤。
  • 'utf16le': 多字節編碼的 Unicode 字符。 與 'utf8' 不同,字符串中的每個字符都會使用 2 個或 4 個字節進行編碼。 Node.js 僅支持 UTF-16 的小端序變體。
  • 'latin1': Latin-1 代表 ISO-8859-1。 此字符編碼僅支持從 U+0000 到 U+00FF 的 Unicode 字符。 每個字符使用單個字節進行編碼。 超出該范圍的字符會被截斷,並映射成該范圍內的字符。
  • 'base64': Base64 編碼。 當從字符串創建 Buffer 時,此編碼也會正確地接受 RFC 4648 第 5 節中指定的 “URL 和文件名安全字母”。 base64 編碼的字符串中包含的空格字符(例如空格、制表符和換行)會被忽略。
  • 'hex': 將每個字節編碼成兩個十六進制的字符。 當解碼僅包含有效的十六進制字符的字符串時,可能會發生數據截斷。 請參見下面的示例。
  • 'ascii': 僅適用於 7 位 ASCII 數據。 當將字符串編碼為 Buffer 時,這等效於使用 'latin1'。 當將 Buffer 解碼為字符串時,則使用此編碼會在解碼為 'latin1' 之前額外取消設置每個字節的最高位。 通常,當在編碼或解碼純 ASCII 文本時,應該沒有理由使用這種編碼,因為 'utf8'(或者,如果已知的數據始終為純 ASCII,則為 'latin1')會是更好的選擇。 這僅為傳統的兼容性而提供。
  • 'binary': 'latin1' 的別名。 有關此編碼的更多背景,請參閱二進制字符串。 該編碼的名稱可能會引起誤解,因為此處列出的所有編碼都是在字符串和二進制數據之間轉換。 對於在字符串和 Buffer 之間進行轉換,通常 'utf-8' 是正確的選擇。
  • 'ucs2': 'utf16le' 的別名。 UCS-2 以前是指 UTF-16 的一種變體,該變體不支持代碼點大於 U+FFFF 的字符。 在 Node.js 中,始終支持這些代碼點。

如有錯誤歡迎指正!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM