vue中封装axios请求、拦截器

Vue中统一封装axios请求

1.axios是什么,为什么要统一封装

axios是一个基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如统一进行拦截请求和响应、取消请求、转换json、客户端防御XSRF等。我们所要的axios的封装和api接口的统一管理,主要目的是帮助我们简化代码,以便于日后的维护。

统一封装axios拦截器和get/post请求

import axios from 'axios'
import { Loading, Message } from 'element-ui' // 这里我是使用elementUI的组件来给提示

let loadingInstance = null // 加载全局的loading

const instance = axios.create({ //创建axios实例,在这里可以设置请求的默认配置
    timeout: 60000, // 设置超时时间60s
    baseURL: process.env.NODE_ENV === 'production' ? '' : 'https://api.apiopen.top' //根据自己配置的反向代理去设置不同环境的baeUrl
})

// 文档中的统一设置post请求头。
// instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

let httpCode = { //这里我简单列出一些常见的http状态码信息,可以自己去调整配置
    400: '(400)请求参数错误',
    401: '(401)权限不足, 请重新登录',
    403: '(403)服务器拒绝本次访问',
    404: '(404)请求资源未找到',
    500: '(500)内部服务器错误',
    501: '(501)服务器不支持该请求中使用的方法',
    502: '(502)网关错误',
    504: '(504)网关超时'
}

/** 添加请求拦截器 **/
instance.interceptors.request.use(config => {
    /**
     * 在这里:可以根据业务需求可以在发送请求之前做些什么。
     * config.headers['token'] = sessionStorage.getItem('token') || ''
     */
    loadingInstance = Loading.service({ // 发起请求时加载全局loading,请求失败或有响应时会关闭
        spinner: 'fa fa-spinner fa-spin fa-3x fa-fw',
        text: '拼命加载中...'
    })
    return config
}, error => {
    // 对请求错误做些什么
    console.log('请求错误,原因:', error)
    return Promise.reject(error)
})

/** 添加响应拦截器  **/
instance.interceptors.response.use(response => {
    loadingInstance.close()
    if (response.data.code === 200) { // 响应结果里的status: 200是我与后台的约定,大家可以根据实际情况去做对应的判断
        return Promise.resolve(response.data)
    } else {
        Message({
            message: response.data.message,
            type: 'error'
        })
        return Promise.reject(response.data.message)
    }
}, error => {
    loadingInstance.close()
    if (error.response) {
        /**
         * 在这里:可以根据业务需求可以在请求失败后做什么。
         * 根据请求失败的http状态码去给用户相应的提示
         */
        let tips = error.response.status in httpCode ? httpCode[error.response.status] : error.response.data.message
        Message({
            message: tips,
            type: 'error'
        })
        return Promise.reject(error)
    } else {
        Message({
            message: '请求失败',
            type: 'error'
        })
        return Promise.reject(new Error('请求失败'))
    }
})

/* 统一封装get请求 */
export const get = (url, params, config = {}) => {
    return new Promise((resolve, reject) => {
        instance({
            method: 'get',
            url,
            params,
            ...config
        }).then(response => {
            resolve(response)
        }).catch(error => {
            reject(error)
        })
    })
}

/* 统一封装post请求  */
export const post = (url, data, config = {}) => {
    return new Promise((resolve, reject) => {
        instance({
            method: 'post',
            url,
            data,
            ...config
        }).then(response => {
            resolve(response)
        }).catch(error => {
            reject(error)
        })
    })
}

/* 或者写成下面这样: Promise.resolve() 和 Promise.reject()返回的是promise对象,二者都是语法糖  */
// export const post = (url, data, config = {}) => {
//     return instance({
//         method: 'post',
//         url,
//         data,
//         ...config
//     }).then(response => {
//         return Promise.resolve(response)
//     }).catch(error => {
//         return Promise.reject(error)
//     })
// }

下面几张图是拦截器的回调函数的参数

  • 请求拦截器中的config
    vue中封装axios请求、拦截器_第1张图片

  • 请求拦截器中的response
    请求拦截器中的response

2.统一进行接口api管理

// 每个模块都应该有自己的接口文件去统一管理api

import {get, post } from '@/api/axios'

export const getDzData = (params) => get('/getJoke', params)

3.页面上的使用

import { getDzData } from '@/api/data';

export default {
  name: 'App',
  data () {
    return {}
  },
  mounted () {
    let params = {
        pageNo,
        count:pageSize,
        type: 'image'
    }
    getDzData(params).then(res => {
        let data = res.result
        console.log(data)
    })
  }
}

4.问题整理

  • 怎么根据不同的接口设置不同的请求头信息,优先级又是怎样的

可以在请求的拦截器里面config,去判断,分别设置。也可以使用已经封装的get/post请求里写,在调用api时,传第三个参数就是config的信息。配置的优先顺序:配置会以一个优先顺序进行合并,这个顺序是:在 lib/defaults.js 找到的库的默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后者将优先于前者。

  • post请求常见的数据格式(Content-Type)
  1. application/json :参数会直接放在请求体中,以JSON格式的发送到后端。这也是axios请求的默认方式。这种类型使用最为广泛。

  2. application/x-www-form-urlencoded:请求体中的数据会以普通表单形式(键值对)发送到后端。

  3. multipart/form-data 参数会在请求体中,以标签为单元,用分隔符(可以自定义的boundary)分开。既可以上传键值对,也可以上传文件。通常被用来上传文件的格式。

最后:如果文章对您有帮助,请点赞,或者留言,有写的不对的地方,多多提出修改意见

详细代码请到GitHub查看

你可能感兴趣的:(axios,vue,http)