- pre-notify
- Node.js支持的編碼
- gb2312
- utf8和隱藏在黑夜中的兇手
- BOM
- BOM的真面目
- 干掉BOM!
- 讓node支持gbk——iconv-lite
- string_decoder
[TOC]
## pre-notify
本文會不斷完善,也歡迎各位大佬一起“打磨”
## Node.js支持的編碼
當我們讀一個文件的時候,可以指定以什么樣的編碼來讀取
```
fs.readFile('./test.txt','utf8',function(err,data){
console.log(data); //打印出來的就是編碼后的字符串
})
```
**注意:**
- Node.js默認支持的編碼有utf8、base64,**不支持**gb系列
- 當**不填**寫編碼時,默認數據的形式**是buffer**
## gb2312
當我們在桌面創建一個.txt時,默認編碼是`gb2312`,而又由于Node.js默認是不支持的,So我們通過`fs`讀取到的`buffer`是轉換不成我們想要的中文文字的。

大多數編輯器打開這些文件時候也會亂碼。

>[warning] **注意:** 即使將txt文件的后綴名更改為`.js`也是一樣的。
## utf8和隱藏在黑夜中的兇手
我們可以將文本另存為`utf8`
這樣雖然能讓中文正常顯示,但我們發現在開始的位置卻出現了亂碼。

這是為什么呢?
在我們使用unicode系編碼的時,因為unicode編碼有很多實現,So它會簽個名,表示這個文件的是utf8編碼的,歸utf8管。這樣我們再使用編輯器打開的時候它就不會亂碼

**what?!** 編輯器打開都不亂碼了,你娃娃node.js讀文件toString還要亂碼?
腳多麻的,讓我們換一個編輯器,嗯,webstorm

**what?!** 不亂碼了?這是為什么!!
嗯。。。不要方!不要方!真相只有一個!!
嘿!我們仔細看,沒亂碼,但變成了一個點 **\`**。
So這個問題有一個合理的推斷,我大webstorm為Node.JS主持了公正!
是vscode私自導致的亂碼,這鍋不該Node.js小兄弟背而該讓vscode背!
嗯。。。雖然webstorm中沒有亂碼,但平白無故多了個 **\`** ,這也不好吧?
## BOM
### BOM的真面目
So,這個 **\`** 是什么?其實我們上面已經說過,如果是unicode系的編碼,都會在開頭簽個名,So這個 **\`** 就是和這個簽名,這個字的16進制形式是長這樣的
```
0xFEFF
```
轉換成buffer是長這樣的
```
<Buffer ef bb bf>
```
嗯。。。現在我們知道它到底是個什么鬼了,So干不干掉它不就是我們幾行代碼的事?
### 干掉BOM!
```
let bf2 = fs.readFileSync(path.join(__dirname,'bom.txt'),'utf8');
let result = stripBOM(bf2);
console.log(result.toString());
// console.log(result);
function stripBOM(content){
if(Buffer.isBuffer(content)){
if(content[0]===0xEF&&content[1]===0xBB&&content[2]===0xBF){
return content.slice(3);
}
return content;
}else{ //是string
if(content.charCodeAt(0)===0xFEFF){
return content.slice(1);
}
return content;
}
}
```
## 讓node支持gbk——iconv-lite
嗯,其實很簡單,一個包的事
```
let iconv = require('iconv-lite');
let string = iconv.decode(需要轉換的buffer,希望用的編碼方式)
console.log(string)
```
## string_decoder
我們通常都是用utf8來編碼的,utf8編碼一個漢字等于3個字節,但有時候我們不一定能一次性拿到完整的數據,可能先拿2個后拿4個,那么第一次拿的時候我們輸出出來就會產生亂碼。
So我們需要一個東東來幫我們看著,當拿到的東西是一個漢字時要湊夠3個字節才輸出,否則就先攢著,這就是`string_decoder`的作用之一。
```
let buffer = Buffer.from('阿彌陀佛');
let buff1 = buffer.slice(0,5);
let buff2 = buffer.slice(5);
let {StringDecoder} = require('string_decoder');
let sd = new StringDecoder();
console.log(sd.write(buff1).toString());
console.log(sd.write(buff2).toString());
```
## encodeURIComponent
設置一些響應頭請求頭什么的如果有中文,需要進行編碼 否則會報錯



