版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xsb_20171227/article/details/86438890
首先大概说一下乱码原因:
由于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;
}
};
下面的链接是关于XMLHttpRequest请求中,中文参数的处理方式
https://blog.csdn.net/xsb_20171227/article/details/86487724