首先大概說一下亂碼原因:
由於nodejs中不認gbk、gb2312等老的編碼,我們獲取這些編碼網站的時候,nodejs會自動按照utf-8解碼,然後就是一堆亂碼問題。
這個時候,內容已經遭到了破壞,即使我們有辦法反編碼,也不可能得到正確的中文了。
我的解決辦法:
在網上查了一天多,經過九九八十一難之後,我的解決辦法終於出來了
首先安裝:iconv-lite(好像項目裏面已經有了,你們自己檢查一下自己的,沒有的話才安)、buffer、stream
後面那兩個都是iconv-lite裏面會使用到的。
網上都是說用http或封裝過http的組件來進行請求,可是我安裝http總是隻有一個package.json文件,反正各種問題,用fetch倒是請求成功了,可是用iconv-lite轉碼的時候,還是有各種問題,所以這裏就用了XMLHttpRequest。
接下來上代碼了。
//這裏是引入
const Buffer = require('buffer').Buffer;
const iconvLite = require('iconv-lite');
/**
*自己寫的一個ajax方法
* @param url 請求路徑
* @param timeout 超時時間 單位是秒
* @param isUtf8 是否爲utf8編碼格式
* @param params 請求參數
* @param async 是否異步
* @param successCallBack 成功回調
* @param failCallBack 失敗回調
* @returns {Promise.<T>|*}
*/
ajax = (url,timeout,isUtf8, params,async, successCallBack,failCallBack) => {
if (params) {
url += '?' + queryString.stringify(params)
}
if(isUtf8 == null){
isUtf8 = true;
}
if(async){
//異步
return new Promise(function(resolve,reject){
var request = new XMLHttpRequest();
if(timeout == null){
timeout = 60 ;//默認一分鐘
}
timeout *= 1000;
var time = false;
var timer = setTimeout(function(){
time = true;
request.abort();
},timeout);
//如果這個網站不是utf8編碼,設置返回格式
if(!isUtf8){
request.responseType = "arraybuffer";//返回一個ArrayBuffer格式的數據
}
request.onreadystatechange = e => {
if (request.readyState === 4) {
if(time){
failCallBack("請求超時:"+url);
}else if(request.status === 200){
//如果沒有超時,手動結束計時
clearTimeout(timer);
//如果這個網站不是utf8編碼,手動轉碼
if(!isUtf8){
// alert("aaa")
//request.response是ArrayBuffer數據,可通過下面的方式得到其中可用的Uint8Array
let b1 = new Uint8Array(request.response);
//Buffer.from(b1,'hex')是把Uint8Array轉化成Buffer類型數據
let htmlStr = iconvLite.decode(Buffer.from(b1,'hex'), 'gbk');
resolve(htmlStr);
}else{
//這個網站是utf8編碼,直接返回字符串形式的html
resolve(request.responseText);
}
}else if(request.status === 404 || request.status === 500 ){
resolve(null);
}
}
}
request.open("GET", url);
request.send();
}).then((data) => {
successCallBack(data);
}).catch((err) => {
failCallBack(err);
});
}else{
//同步,不過好像nodejs裏面請求網站不允許使用同步
var request = new XMLHttpRequest();
request.open("GET", url, async); // 同步請求
request.send();
return request.responseText;
}
};