首頁  >  文章  >  web前端  >  關於Nodejs服務端字元編解碼與亂碼的處理

關於Nodejs服務端字元編解碼與亂碼的處理

不言
不言原創
2018-06-30 11:12:372295瀏覽

這篇文章主要介紹了Nodejs進階之服務端字元編解碼和亂碼處理,具有一定的參考價值,有興趣的小夥伴們可以參考一下

##寫在前面

在web服務端開發中,字元的編解碼幾乎每天都要打交道。編解碼一旦處理不當,就會出現令人頭痛的亂碼問題。

不少從事node服務端開發的同學,由於對字元編碼碼相關知識了解不​​足,遇到問題時,經常會一籌莫展,花大量的時間在排查、解決問題。

文字先對字元編解碼的基礎知識進​​行簡單介紹,然後舉例說明如何在node中進行編解碼,最後是服務端的程式碼案例。本文相關程式碼範例可在這裡找到。

關於字元編解碼

在網路通訊的過程中,傳輸的都是二進位的位元位,不管發送的內容是文字還是圖片,採用的語言是中文還是英文。

舉個例子,客戶端向服務端發送"你好"。

客戶端 --- 你好 ---> 服務端

這中間包含了兩個關鍵步驟,分別對應的是編碼、解碼。


1.客戶端:將"你好"這個字串,編碼成電腦網路所需的二進位位元。


2.服務端:將接收到的二進位位元,解碼成"你好"這個字串。

總結一下:


1.編碼:將需要傳送的數據,轉成對應的二進位位元。


2.解碼:將二進位位元,轉換成原始的資料。

上面有些重要的技術細節沒有提到,答案在下一小節。

  • 客戶端怎麼知道"你好"這個字元對應的位元位是多少?

  • 服務端收到二進位位元組之後,怎麼知道對應的字串是什麼?

關於字元集和字元編碼

上面提到字元、二進位的轉換問題。既然兩者可以互相轉換,也就是說有明確的轉換規則,可以實現字元e09be6022d700e04aeaa85a5f42fdcb2二進位的相互轉換。

這裡提到的轉換規則,其實就是我們常聽到的字元集&字元編碼。

字元集是一系列字元(文字、標點符號等)的集合。字元集有很多,常見的有ASCII、Unicode、GBK等。不同字元集主要的差異在於包含字元個數的不同。

了解了字元集的概念後,接下來介紹下字元編碼。

字符集告訴我們支援哪些字符,但具體字符怎麼編碼,是由字符編碼決定的。例如Unicode字元集,支援的字元編碼有UTF8(常用)、UTF16、UTF32。

概括一下:

  • 字元集:字元的集合,不同字元集包含的字元數不同。

  • 字元編碼:字元集中字元的實際編碼方式。

  • 一個字元集可能有多種字元編碼方式。

可以把字元編碼看成一個映射表,客戶端、服務端就是根據這個映射表,來實現字元跟二進位的編解碼轉換。

舉個例子,"你"這個字符,在UTF8編碼中,佔據三個字節0xe4 0xbd 0xa0,而在GBK編碼中,佔據兩個字節0xc4 0xe3。

字元編解碼範例

上面已經提到了字元編解碼所需的基礎知識。下面我們來看一個簡單的例子,這裡藉助了icon-lite這個函式庫來幫助我們實作編解碼的操作。

可以看到,當字元編碼時,我們採用了gbk。在解碼時,如果同樣採用gbk,可以得到原始的字元。而當我們解碼時採用utf8時,則出現了亂碼。

var iconv = require('iconv-lite');

var oriText = '你';

var encodedBuff = iconv.encode(oriText, 'gbk');
console.log(encodedBuff);
// <Buffer c4 e3>

var decodedText = iconv.decode(encodedBuff, &#39;gbk&#39;);
console.log(decodedText);
// 你

var wrongText = iconv.decode(encodedBuff, &#39;utf8&#39;);
console.log(wrongText);
// ��

實際範例:服務端編解碼

#通常我們需要處理編解碼的場景有檔案讀寫、網路請求處理。這裡距網路請求的例子,介紹如何在服務端進行編解碼。

假設我們執行以下http服務,監聽來自客戶端的請求。客戶端傳輸資料時採用了

gbk編碼,而服務端預設採用的是utf8編碼。

如果此時採用預設的

utf8對請求進行解碼,就會出現亂碼,因此需要特殊處理。

服務端程式碼如下(為簡化程式碼,這裡跳過了請求方法、請求編碼的判斷)

#

var http = require(&#39;http&#39;);
var iconv = require(&#39;iconv-lite&#39;);

// 假设客户端采用post方法,编码为gbk
var server = http.createServer(function (req, res) {
  var chunks = [];
  
  req.on(&#39;data&#39;, function (chunk) {
    chunks.push(chunk)
  });

  req.on(&#39;end&#39;, function () {
    chunks = Buffer.concat(chunks);

    // 对二进制进行解码
    var body = iconv.decode(chunks, &#39;gbk&#39;);
    console.log(body);

    res.end(&#39;HELLO FROM SERVER&#39;);
  });

});

server.listen(3000);

##對應的客戶端程式碼如下:

var http = require(&#39;http&#39;);
var iconv = require(&#39;iconv-lite&#39;);

var charset = &#39;gbk&#39;;

// 对字符"你"进行编码
var reqBuff = iconv.encode(&#39;你&#39;, charset);

var options = {
  hostname: &#39;127.0.0.1&#39;,
  port: &#39;3000&#39;,
  path: &#39;/&#39;,
  method: &#39;POST&#39;,
  headers: {
    &#39;Content-Type&#39;: &#39;text/plain&#39;,
    &#39;Content-Encoding&#39;: &#39;identity&#39;,
    &#39;Charset&#39;: charset // 设置请求字符集编码
  }
};

var client = http.request(options, function(res) {
  res.pipe(process.stdout);
});

client.end(reqBuff);

以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!

相關推薦:

關於nodejs socket服務端和客戶端的簡單通訊功能

如何在NodeJS專案中使用ES6

以上是關於Nodejs服務端字元編解碼與亂碼的處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn