ReactNative 封装 fetch 网络请求 (附 Base64加解密 和 Json解析 工具类)

Demo: https://github.com/YouCii/RNDemo

转到 RN 之后还是不自主地按照 android 的方式搭框架, 今天把 fetch 封装到了 HttpUtils 里.

import JsonUtils from "./JsonUtils";
import EncodeUtils from "./EncodeUtils";

/**
 * 返回Promise对象的网络请求工具类
 * 封装了请求超时/部分错误提示等
 */
export default class HttpUtils {

    /**
     * 开启GET请求
     * @param url       请求地址
     * @param params    GET请求参数,Map
     * @return promise对象
     */
    static startGetRequest(url: String, params: Map) {
        if (params != null && params.size !== 0) {
            url += "?";
            params.forEach((value, key) => {
                url += (key + "=" + value + "&");
            });
            url = url.substr(0, url.length - 1)
        }
        return Promise.race([fetch(url, {
            method: "Get",
            credentials: "include"
        }), new Promise(((resolve, reject) => {
            setTimeout(() => reject(new Error('请求超时')), timeOut)
        }))])
            .then((response: Response) => checkStatus(response))
            .then((response: Response) => {
                return response.text()
            })
            .then((responseText: String) => {
                return JsonUtils.stringToJson(responseText);
            })
    }

    /**
     * 开启POST请求(测试没有问题)
     * @param url       请求地址
     * @param params    POST请求参数,Map
     * @return promise对象
     */
    static startPostRequest = (url: String, params: Map) => {
        let formData = new FormData();
        if (params != null && params.size !== 0) {
            params.forEach((value, key) => {
                formData.append(key, value);
            })
        }

        return Promise.race([fetch(url, {
            method: "POST",
            credentials: "include",
            body: formData,
        }), new Promise((resolve, reject) => {
            setTimeout(() => reject(new Error('请求超时')), timeOut)
        })])
            .then((response: Response) => checkStatus(response))
            .then((response: Response) => {
                return response.text()
            })
            .then((responseText: String) => {
                // 是否需要解密之类的判断
                if (responseText.indexOf("\"data\"") === -1 
                && responseText.indexOf("\"message\"") === -1 
                && responseText.indexOf("\"msg\"") === -1) {
                    responseText = EncodeUtils.decodeBase64Content(responseText);
                }
                return JsonUtils.stringToJson(responseText);
            })
    }

}

/**
 * 请求超时时间
 */
const timeOut = 5 * 1000;

/**
 * 解决fetch不提示某些错误的问题
 */
function checkStatus(response) {
    if (response.ok || (response.status >= 200 && response.status < 300)) {
        return response;
    }
    throw new Error(response.statusText); // 或者 reject(new Error('test'));
}

上面是使用 response.text() 拿到了回调字符串, 如果回调肯定是一个无需额外处理的 json 的话, 可以使用 response.json() 直接拿到实体类.

HttpUtils 的具体使用:

let params = new Map();
params.set('start', 0);
params.set('count', toSelectNum);
HttpUtils.startGetRequest("https://api.douban.com/v2/movie/top250", params)
    .then(responseJson => {
        // responseJson.subjects[0].images.large 就是实体类内的数据
        Image.getSize(responseJson.subjects[0].images.large, (width, height) => {
            this.setState({
                imageRadio: height / width,
                topMovieResponse: responseJson,
            });
        })
    })
    .catch(error => {
        AlertUtils.showSimpleAlert('请求失败' + error);
    });

附 Base64加解密工具类

import {Buffer} from "buffer" // npm install --save buffer

/**
* Base64加解密
*/
export default class EncodeUtils {
    /**
     * 加密
     */
    static encodeBase64Content(content) {
        return new Buffer(content).toString('base64')
    }
    /**
     * 解密
     */
    static decodeBase64Content(base64Content) {
        return new Buffer(base64Content, 'base64').toString();
    }
}

Json解析工具类

export default class JsonUtils {
    /**
     * 字符串转json
     */
    static stringToJson(data) {
        return JSON.parse(data);
    }

    /**
     * json转字符串
     */
    static jsonToString(data) {
        return JSON.stringify(data);
    }

    /**
     * map转换为json
     */
    static mapToJson(map) {
        return JSON.stringify(strMapToObj(map));
    }

    /**
     * json转换为map
     */
    static jsonToMap(jsonStr) {
        return objToStrMap(JSON.parse(jsonStr));
    }
}

/**
 * map转化为对象(map所有键都是字符串,可以将其转换为对象)
 */
function strMapToObj(strMap) {
    let obj = Object.create(null);
    for (let [k, v] of strMap) {
        obj[k] = v;
    }
    return obj;
}

/**
 * 对象转换为Map
 */
function objToStrMap(obj) {
    let strMap = new Map();
    for (let k of Object.keys(obj)) {
        strMap.set(k, obj[k]);
    }
    return strMap;
}

你可能感兴趣的:(ReactNative,ReactNative学习历程)