06月07, 2017

axios的简单用法

最近在做react的一个项目,对axios的一些用法,也算熟悉了一些。此篇文章算是我的一个简单总结。

二次封装

二次封装,基于的考虑是axios在实际的场景并不能单纯地使用,比如说类似以下场景:

if (data.head && data.head.status == "Y") {  // 判断status为yes,才可以做一些事
      // TODO something
}

显然每个请求回来后的数据,都做一下这个判断是不合理的。

官方API提供了Interceptors的功能,然而我觉得这个并不能用上面的需求中。因为上面的判断,当status为’N‘的时候,它还是会往下输出,并不能中止。

这里补充一下:可以直接return Promise.reject('')。这样的写法,then接收的是reject,而非resolve,就能处理上面说的中止的问题了。

所以其实官方的Interceptors不能叫拦截器,而应该是叫中间件,对中间的数据进行二次封装。

第二种需求,session失效需要重定向页面:

// code一般是后端提供的
 if (code === "11111114") {
       message.error(errorInfo, 2, () => {
           browserHistory.push('/login');
           localStorage.clear();
       })
       return;
}

这种其实算是第一种需求的一个扩展。

第三种需求,不同的contentType应对。

这边在和后端聊天时,发现他们请求是这样处理的:

1、获取数据,一般为get,然后将参数拼在url后面即可。

2、提交数据(如保存),字段结构简单的,用form的方式提交;字段复杂的,比如说数组、对象,用application/json的方式提交

2里面其实还有一种情况,就是file,文件类型的提交,他们后端用的是form-data,对应的’Content-Type‘为“multipart/form-data”。

所以contentType就有了以下三种情况:

  • application/json
  • application/x-www-form-urlencoded
  • multipart/form-data

基于上面的原因,我觉得有必要在项目中二次封装一下axios的代码。。以下是我基于业务封装的一个代码(略丑,当然也待改进)

import axios from "axios";

import { message } from "antd";

import { browserHistory } from 'react-router';

import querystring from 'querystring';

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

const request = {
    handleData: function (res, resolve, reject) {
        let data = res.data;
        if (data.head && data.head.status == "Y") {
            resolve(data.body);
        }else {
            message.destroy();
            let code = data.head.code,
                errorInfo = data.head.msg;
            if (code === "11111114") {
                message.error(errorInfo, 2, () => {
                    browserHistory.push('/login');
                    localStorage.clear();
                })
                return;
            }
            message.error(errorInfo, 3);
            reject && reject();
        }
    },
    post: function (url, params, type) {
        let _this = this,
            config = {};
        if (type && type == "json") {
            config = {
                headers: {
                    post: {
                        'Content-Type': 'application/json'
                    }
                }
            }
        } else if (type && type == "file") {
            config = {
                headers: {
                    post: {
                        'Content-Type': 'multipart/form-data'
                    }
                }
            }
        } else {
            params = querystring.stringify(params);
        }
        return new Promise((resolve, reject) => {
            axios.post(url, params, config).then((res) => {
                _this.handleData(res, resolve, reject);
            })
        })
    },
    get: function (url) {
        let _this = this;
        return new Promise((resolve, reject) => {
            axios.get(url).then((res) => {
                _this.handleData(res, resolve, reject);
            })
        })
    }
}

export default request;

请求独立

有了上面的request.js,我们基于它就可以把所有的请求都放在一个文件中,代码如下:

import request from "./request";

import querystring from 'querystring'

const API = {
   'create_application': '/rest/application/create',
    'env_list': '/rest/env/list',
    'version_list': '/rest/web/config/versions',
    'create_item': '/rest/web/config/createItem',
    'create_file': '/rest/web/config/createFile'
}

export const createApplication = (params) => request.post(API.create_application, params);

export const getEnvList = () => request.get(API.env_list);

export const getVersionList = (params) => request.get(API.version_list + "?" + querystring.stringify(params));

export const createItem = (params) => request.post(API.create_item, params, 'json');

export const createFile = (params) => request.post(API.create_file, params, 'file');

以上把get以及post的情况都考虑全了。。当然我司并没有用到resful api,如果用它的话,我上面的代码还得再改造一下。

请求文件

很早之前我就有一个误区,认为jQuery的ajax无法实现文件上传,一定要用ajaxUpload插件才行。

当然这是错误的,感谢这几年H5的发展,我们很少去考虑浏览器的兼容,所以完全可以使用formData来处理。

let params = new FormData();
params.append("a", 1);
params.append("b", 2);
params.append('file', file);

formData的获取也是很有意思,它必须用get key的方式,来得到值,这样一来,我们也可以区别它和普通的json对象。

form-data

本文链接:www.my-fe.pub/post/simple-use-axios.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。