React项目中请求接口的封装

4,939 阅读3分钟

封装目录中所包含的文件

  • Api.js

  • ApiIp.js

  • ApiURL.js 

           

ApiIp.js文件的作用

这个文件的作用主要是在开发环境和生产环境下调用不同的接口请求地址,生产环境下此文件的作用是动态 的获取浏览器中的地址进行拼装,便可以动态的获取地址,不需要写死

//获取当前的URL中的地址,同时携带端口号,不携带http://
let projectAddrass = window.location.host;
let projectAddrassNoPort = window.location.hostname;
//返回当前的URL协议,既http协议还是https协议
let protocol = document.location.protocol;
//封装请求接口的地址,如果服务器中套了一层性项目名称,需要在这里面添加上,需要留意,例如: /zzxl/
export const interfaceIp = `${protocol}//${projectAddrass}/zzxl`;
//LOGO图片的请求地址
export const logoImgAddress = `${protocol}//${projectAddrassNoPort}`;
//对外提供的服务地址
export const publicIp = process.env.NODE_ENV === 'development' ? 'http://10.222.40.243:8088' :
interfaceIp;
export const logoImgIp = process.env.NODE_ENV === 'development' ? 'http://127.0.0.1' :
logoImgAddress;

ApiURL.js文件的作用

引入ApiIp.js传入的地址,并且封装上具体的请求路径,拼装成完整的请求地址,这样可以把所有的接口请求 地址放到一个文件中,降低耦合度,便于维护。

import ApiIP from './ApiIp';
// 登录
export const LOGIN = `${ApiIP}/index/captcha`;

Api.js文件的作用

对外请求接口服务的入口文件,借助于axios 的再次封装,返回为Promise 对象,因为Promise对象含有 then、catch方法 便于进一步的处理。

import axios from 'axios';
import * as apiUrl from './ApiURL';
import {notification} from 'antd';
​
const key = 'keepOnlyOne';
​
/**
 *  接口请求数据时执行的方法
 *  接受参数为请求的路径apiUrl、请求接口配置参数configObj
 *
 * @param {String} apiUrl            用户传入的请求路径
 * @param {Object} configObj        用户传入的接口参数
 */
function getDataFromServer(apiUrl, configObj) {
​
    //用户传入的接口配置参数
    let {
        method = 'GET',
        params = {},
        data = {},
        timeout = 5000
    } = configObj;
​
    /**
     * 返回的Promise对象含有then、catch方法
     */
    return new Promise(function (resolve, reject) {
        axios({
            url: apiUrl,
            method: method,
            params: params,
            data: data,
            timeout: timeout,
            headers: {
                'Content-Type': 'application/json',
                'token': window.sessionStorage.getItem('token') || ''
            }
        }).then(function (response) {
            if(response){
                if (response.data && response.data.code) {
                    resolve(response);
                }else {
                    notification.error({
                        key,
                        message: '操作失败',
                        description: '返回的数据格式有误'
                    });
                    resolve(response);
                }
            }else {
                //处理特殊的情况就是response返回什么也没有
                notification.error({
                    key,
                    message: '操作失败',
                    description: '服务器错误'
                });
                resolve(response);
            }
        }).catch(function (error) {
            notification.error({
                key,
                message: '操作失败',
                description: '网络异常,请稍后重试'
            });
            reject(error);
        })
    })
}
​
​
// 登录
export function loginClick(configObj) {
    return getDataFromServer(apiUrl.LOGIN, configObj);
}

其他组件使用的Dome

// 先引入组件
import { loginClick } from '../Api';
// 使用
let loginInfo = {
method: 'POST',
data: {
account: username
}
}
loginClick(loginInfo).then((response) => {
// do something
}).catch((error)=>{
    // error something
})

一种特殊的请求接口

以post方式出入数据,得到流,下载文件。需要特别的处理。

import axios from 'axios';
import {notification} from 'antd';
​
/**
 * 导出表中选中部分数据
 * 1.exportArray、downLoadURL为必填选项
 * 2.当downLoadFileName为null时,按默认名称下载
 * 3.当_this、stateName为null时,导出完成后不清空选中,不为null时,导出完成后清空选中
 *
 * @param {Array}  exportArray          部分导入传入的数组
 * @param {String} downLoadFileName     下载的下来的文件名字
 * @param {String} downLoadURL          服务请求的地址
 * @param {String} _this                this
 * @param {String} stateName            命名的state的名字
 */
​
export function getStreamData(exportArray, downLoadFileName, downLoadURL, _this, stateName) {
​
    //如果传入的数组为空直接返回
    if (!(exportArray.length > 0)) {
        notification.warn({
            message: '请先选择导出的数据',
            description: '没有选择要导出的数据无法进行导出'
        });
        return;
    }
​
    axios({
        method: 'post',
        url:downLoadURL,
        data: JSON.stringify(exportArray),
        headers: {
            'Content-Type': 'application/json',
            'token': window.sessionStorage.getItem('token') || ''
        },
        responseType: 'blob'
    }).then((response) => {
        if(response){
            const blob = new Blob([response.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'});
            //下载文件的名称
            let filename = 'excel.xlsx';
            if (downLoadFileName) {
                filename = downLoadFileName;
            }
            //非IE浏览器通过download属性进行下载
            if('download' in document.createElement('a')){
                let downloadElememt = document.createElement('a');
                let href = '';
                if(window.URL){
                    href = window.URL.createObjectURL(blob);
                }else {
                    href = window.webkitURL.createObjectURL(blob);
                }
                downloadElememt.href = href;
                downloadElememt.download = filename;
                document.body.appendChild(downloadElememt);
                downloadElememt.click();
                if(window.URL){
                    window.URL.revokeObjectURL(href);
                }else {
                    window.webkitURL.revokeObjectURL(href);
                }
                // 导出成功之后清空选中的数据
                if (_this && stateName) {
                    _this.setState({
                        [stateName]: []
                    });
                }
            }else {
                // IE浏览器,通过navigator进行下载,支持IE10+
                if (navigator.msSaveBlob) {
                    // 导出成功之后清空选中的数据
                    if (_this && stateName) {
                        _this.setState({
                            [stateName]: []
                        });
                    }
                    return navigator.msSaveBlob(blob, filename);
                }
            }
        }else {
            notification.warn({
                message: '导出选中数据失败',
                description: '调用接口导出选中的数据失败'
            });
        }
​
    }).catch(() => {
        notification.error({
            message: '操作失败',
            description: '网络异常,请稍后重试'
        });
    })
}