關於android的RN項目爬去html內容的中文亂碼問題

首先大概說一下亂碼原因:
       由於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;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章