对 Axios 进行简单封装

栏目: jQuery · 发布时间: 5年前

内容简介:对对于将网络错误、HTTP 错误和返回值错误合并,方便上层处理。服务端返回的数据至少包含

Axios 进行简单封装。

二、目标

1、异常处理

对于将网络错误、HTTP 错误和返回值错误合并,方便上层处理。

服务端返回的数据至少包含 codemessage 字段。 code200 时为正常返回。

2、支持跳转 URL

服务端返回的数据如果包含 url 字段,则自动跳转至对应地址。

备注:如果包含 url 字段,不会对 code 进行判断。

3、JSON 序列化

对于 postputpatch 方法提交的数据,序列化成 JSON 。

4、QueryString 序列化

对于 getdeletehead 方法提交的数据,序列化成 QueryString 。

5、同时支持 JOSN 和 文件下载

服务器可能返回不同的数据格式,比如返回文件或 JSON 格式————当文件由于某些原因不可下载时返回 JSON 格式。

6、封装 Vue plugin

Axios 的实例封装成一个 plugin ,方便 Vue.use(xxxx) 。

三、实现

import axios from 'axios'
import qs from 'qs'
import { baseURL } from './config.js'

const SuccessCode = 200

// 自定义错误
const ErrorType = {
  'Default': 'default',
  'Sysetem': 'sysetem'
}

function ApiError (message, errorType, innerError) {
  this.name = 'ApiError'
  this.message = message || 'Default Message'
  this.errorType = errorType || ErrorType.Default
  this.innerError = innerError
  this.stack = (new Error()).stack
}
ApiError.prototype = Object.create(Error.prototype)
ApiError.prototype.constructor = ApiError

const httpClient = axios.create({
  baseURL: baseURL,
  timeout: 20000,
  // 响应的数据格式 json / blob / document / arraybuffer / text / stream
  responseType: 'json',
  withCredentials: true
})

// POST传参序列化(添加请求拦截器)
httpClient.interceptors.request.use(
  config => {
    // 在发送请求之前做某件事
    if (
      config.method === 'post' ||
      config.method === 'put' ||
      config.method === 'patch'
    ) {
      // Content-Type 对于 POST、PUT 和 PATCH 才有意义
      config.headers = {
        // 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        'Content-Type': 'application/json; charset=UTF-8'
      }
      // 序列化
      config.data = JSON.stringify(config.data)
    } else if (
      config.method === 'delete' ||
      config.method === 'get' ||
      config.method === 'head'
    ) {
      // QueryString 序列化器
      config.paramsSerializer = function (params) {
        // arrayFormat: indices brackets repeat
        return qs.stringify(params, {
          arrayFormat: 'indices'
        })
      }
    }

    // 若是有做鉴权token , 就给头部带上token
    if (localStorage.token) {
      config.headers.Authorization = localStorage.token
    }
    return config
  },
  error => {
    return error
  }
)

// 返回状态判断(添加响应拦截器)
httpClient.interceptors.response.use(
  response => {
    if (response.headers['content-type'].indexOf('json') === -1) {
      // 返回的数据不是 json (或是 json 但服务器的 content-type 设置不准确)
      return response
    }
    // 仅处理 json 数据
    let json
    if (response.request.responseType === 'arraybuffer' && response.data.toString() === '[object ArrayBuffer]') {
      // 返回的数据是 arraybuffer,内容是 json
      // 备注:可能内容不是 json,这里暂未处理
      const text = Buffer.from(response.data).toString('utf8')
      console.log(text)
      json = JSON.parse(text)
    } else {
      // 备注:不是 arraybuffer 可能会是 blob 等,这里暂未处理
      json = response.data
    }

    if (json && json.url) {
      top.location = json.url
    } else if (json && json.code !== SuccessCode) {
      console.log(json)
      return Promise.reject(new ApiError(json.message))
    }
    return response
  },
  error => {
    // 返回 response 里的错误信息
    return Promise.reject(new ApiError(error.message, ErrorType.Sysetem, error))
  }
)

// 将 Axios 的实例封装成一个 plugin ,方便 Vue.use(xxxx)
export default {
  install: function (Vue, option = {}) {
    // 1.通过 Vue.httpClient 调用
    Vue.httpClient = httpClient
    // 2.通过 this.$httpClient 调用
    Vue.prototype.$httpClient = httpClient
  }
}

config.js 内容:

export const baseURL = 'http://www.yourdomain.com/api'

四、使用

1、Vue 配置

// ......
import Vue from 'vue'
import HttpClient from '@/utils/httpclient.js'

import App from './App.vue'

Vue.use(HttpClient)
// ......

2、示例

login () {
    const params = {
        username: 'test',
        password: '123456'
    }
    Vue.httpClient.post('/login', params).then(response => {
        console.log(response.data)
    }, error => {
        // error 为 ApiError 实例。对于网络错误或 HTTP 错误等系统错误,可通过 innerError 查询实际错误。
        console.log(error)
    })
}

3、下载支持

const fileDownload = require('js-file-download')

testDownload () {
    const url = 'http://www.yourdomain.com/somefile.zip'
    const params = {
        token: '35dea0e5-9b9f-4b8b-981e-2e1120b1c317'
    }
    Vue.httpClient.post(url, params, {
      // 重要
      responseType: 'arraybuffer'
    }).then(response => {
        fileDownload(response.data, 'somefile.zip')
    }, error => {
        console.log(error)
    })
}

参考资料


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Zen of CSS Design

The Zen of CSS Design

Dave Shea、Molly E. Holzschlag / Peachpit Press / 2005-2-27 / USD 44.99

Proving once and for all that standards-compliant design does not equal dull design, this inspiring tome uses examples from the landmark CSS Zen Garden site as the foundation for discussions on how to......一起来看看 《The Zen of CSS Design》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换