1. 程式人生 > 實用技巧 >NodeJS中Buffer與字串相互轉換時一個值得注意的問題

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 中,始終支援這些程式碼點。

如有錯誤歡迎指正!