Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

axios封装(一)基础配置 #5

Open
some-code opened this issue Jun 1, 2018 · 0 comments
Open

axios封装(一)基础配置 #5

some-code opened this issue Jun 1, 2018 · 0 comments
Labels

Comments

@some-code
Copy link
Owner

some-code commented Jun 1, 2018

axios 是目前流行的Promise网络请求库,在浏览器端他通过 xhr方式创建ajax请求。在node环境下,通过 http 库创建网络请求。

axios 提供了丰富的配置,这里讲一讲我在工作中通常用到的基本配置方法。

因为我在工作中用 vue 进行开发,所以以下代码默认的环境是 vue-cli

创建一个 axios 实例

为什么要创建一个 axios 实例,而不是在 axios 对象上进行配置呢?是因为我们会应对复杂的使用场景,多个实例便于管理。

const isDev = process.env.NODE_ENV === 'development';

const instance = axios.create({
  // baseURL是在proxyTable中会转发的配置,通过环境变量的判断,可以在开发和生产环境使用不同的url进行请求
  baseURL: isDev ? '/fakeapi' : '/api',
  timeout: 5000,

  validateStatus(status) {
    // 一般来说,http status为200-300之间时,均判定为请求通过,你可以在这里修改这个配置(不建议修改)
    return status === 200
  },
  headers: {
    // 定义 post 请求编码格式
    post: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    }
  }
});

处理请求参数

虽然对请求设置了编码格式,但是还是需要进一步设置具体的编码格式,比如我想进行一些特殊的设置。

qs.stringify 这里的参数请参考这篇文章 qs.js - 更好的处理url参数

import Qs from 'qs';

instance.interceptors.request.use(config => {
    // 也可以在这里给请求添加token之类的字段
    config.data = Qs.stringify(config.data, {arrayFormat: 'repeat', allowDots: true});
    return config;
}, err => {
    return Promise.reject(err);
});

处理返回值

import httpErrorHandler from './httpErrorHandler.js';

instance.interceptors.response.use(function(data) {
    // 这里可以对返回数据进行处理,比如验证code是否为1等
    return data.data;
}, httpErrorHandler)

httpErrorHandler.js 代码

# httpErrorHandler.js

export default (error) => {
  if (!error.response) {
    return Promise.reject({
        msg: '网络连接超时',
        error
    });
  };

  let msg = '';
  const status = error.response.status;

  switch (status) {
    case 400:
        msg = '错误的请求参数';
        break;
    case 401:
        msg = '没有该操作权限';
        break;
    case 403:
        msg = '请登录';
        break;
    case 404:
        msg = '错误的请求地址';
        break;
    case 500:
    case 501:
    case 502:
    case 503:
    case 504:
        msg = '服务器错误';
        break;
    default:
        msg = '未知错误' + status;
  }
  return Promise.reject({
      msg,
      error
  });
}

封装 get 方法

jquery.ajax 不同,axios的get方式需要通过 prarms 而不是 data参数传递:

/**
 * 封装后的axios get方法
 *
 * @param {string} url 请求路径
 * @param {object} option 请求参数
 * @param {object} [config] 特殊配置项(选填)
 * @returns
 */
export function get(url, option, config = {}) {
  return instance.get(url, { params: option }, config)
}

// 调用get
get('http://baidu.com', {
    a: 1,
    b: 2
})
.then(...)
.catch(...)

post 方式

post请求方式则要简单一些,不需要使用 prarms 参数

/**
 * 封装后的axios post方法
 *
 * @param {string} url 请求路径
 * @param {object} option 请求参数
 * @param {object} [config] 特殊配置项(选填)
 * @returns
 */
export function get(url, option, config = {}) {
  return instance.get(url, option, config)
}

// 调用post
post('http://baidu.com', {
    a: 1,
    b: 2
})
.then(...)
.catch(...)

upload 文件

上传文件需要使用不同的header设置和编码方式,所以需要创建一个单独的实例

const uploadInstance = axios.create({
  baseURL: isDev ? '/fakeapi' : '/api',
  timeout: 15000,
  headers: {
    // 发送文件需要的编码格式
    'Content-Type': 'multipart/form-data'
  }
});

/**
 * 封装后的axios upload方法
 *
 * @param {string} url 请求路径
 * @param {object} option 请求参数
 * @param {object} [config] 特殊配置项(选填)
 * @returns
 */
export function get(url, option, config = {}) {
  let formdata = new FormData();
  Object.keys(option).forEach(key=>{
      formdata.append(key, option[key])
  })
  return uploadInstance.post(url, formdata, config)
}

# 使用上传
let data = {
    a: 1,
    image: input.files[0],
}
let config = {
    onUploadProgress(progressEvent) {
    // 展示上传进度等
    }   
}

upload('http://baidu.com', data, config)
@some-code some-code added the http label Jun 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant