对 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)
    })
}

参考资料


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

查看所有标签

猜你喜欢:

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

深入浅出强化学习:原理入门

深入浅出强化学习:原理入门

郭宪、方勇纯 / 电子工业出版社 / 2018-1 / 79

《深入浅出强化学习:原理入门》用通俗易懂的语言深入浅出地介绍了强化学习的基本原理,覆盖了传统的强化学习基本方法和当前炙手可热的深度强化学习方法。开篇从最基本的马尔科夫决策过程入手,将强化学习问题纳入到严谨的数学框架中,接着阐述了解决此类问题最基本的方法——动态规划方法,并从中总结出解决强化学习问题的基本思路:交互迭代策略评估和策略改善。基于这个思路,分别介绍了基于值函数的强化学习方法和基于直接策略......一起来看看 《深入浅出强化学习:原理入门》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具