关于android的RN项目爬去html内容的中文乱码问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 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

猜你喜欢

转载自blog.csdn.net/xsb_20171227/article/details/86438890
今日推荐