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

什麼問題

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

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

補充

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

  • '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 中,始終支持這些代碼點。

若有錯誤歡迎指正!安全

相關文章
相關標籤/搜索