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
-
请求拦截器中的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)
-
application/json :参数会直接放在请求体中,以JSON格式的发送到后端。这也是axios请求的默认方式。这种类型使用最为广泛。
-
application/x-www-form-urlencoded:请求体中的数据会以普通表单形式(键值对)发送到后端。
-
multipart/form-data 参数会在请求体中,以标签为单元,用分隔符(可以自定义的boundary)分开。既可以上传键值对,也可以上传文件。通常被用来上传文件的格式。
最后:如果文章对您有帮助,请点赞,或者留言,有写的不对的地方,多多提出修改意见
详细代码请到GitHub查看