二次封装Axios
通常在一个企业级或者个人开源的项目中,Axios会被二次封装。
二次封装的好处有哪些呢?
- 统一 url 配置
- 统一 api 请求
- request (请求)拦截器,例如:带上token等,设置请求头
- response (响应)拦截器,例如:统一错误处理,页面重定向等
- 统一处理http错误码和自定义的code
话不多说,我们直接开始吧!
创建src\utils\axiosUtil.js
。
这个文件就是用来封装Axios,我们想要在其他文件中使用Axios,这里我们就需要创建并抛出一个Axios实例。
import axios from "axios"
let axiosInstance = axios.create({
})
export default axiosInstance;
接下来,我们就开始进行配置。打开http://axios-js.com/zh-cn/docs/index.html#请求配置查看Axios提供的配置项。
基本配置
统一url配置
首先,我们需要配置的是统一的请求接口。我们在src\views\AddTutorial.vue
直接使用axios发post请求http://localhost:3000/api/tutorials
,这里的http://localhost:3000/api
就是一个统一的Url。
let axiosInstance = axios.create({
baseURL:'http://localhost:3000/api',
})
有了这个baseURL在发送post请求的时候,就不需要加上http://localhost:3000/api
,Axios会自动给我们加上!!!
环境变量
但是http://localhost:3000/api
这个只是本地测试的接口,我们还有服务器测试接口,上线后的接口。针对不同接口,我们每次都需要修改,是一件很麻烦的事情,还好我们使用的是node(npm)作为的辅助开发工具。他天生自带一个process全局变量。并且Vue/CLI创建的项目,支持设置模式和环境变量。
模式是 Vue CLI 项目中一个重要的概念。默认情况下,一个 Vue CLI 项目有三个模式:
development
模式用于vue-cli-service serve
test
模式用于vue-cli-service test:unit
production
模式用于vue-cli-service build
和vue-cli-service test:e2e
更多内容我们可以直接去 https://cli.vuejs.org/zh/guide/mode-and-env.html查看更多信息。
我们在项目根目录下创建两个文件,并加上环境变量键值对。
-
.env.development
VUE_APP_APIURL=http://localhost:3000/api
-
.env.production
VUE_APP_APIURL=发布环境接口
.env.development存放开发环境api url。,.env.production存放发布环境api url。
有了这个怎么使用呢?
指定mode
在package.json.scripts中,我们目前有两个脚本,一个是用来启动本地服务,一个用来打包。
其实这两个脚本后面都有一个默认的mode.
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
完整的代码应该是;
"serve": "vue-cli-service serve --mode developemnt",
"build": "vue-cli-service build --mode production"
–mode developemnt 会使用.env.development的值
–mode developemnt 会使用.env.production的值
使用process.env
我们刚才说了,全局有一个process,它上面挂载了env。通过env找到我们的VUE_APP_APIURL
我们修改axiosUtils
let axiosInstance = axios.create({
baseURL:process.env.VUE_APP_APIURL,
})
当我们执行yarn serve
yarn build
,就会切换到对应的值。
请求头
我们后端支持支持什么格式的数据,这里就可以指定具体的Content-type。我们这个项目就指定json即可
import axios from "axios"
let axiosInstance = axios.create({
baseURL:process.env.VUE_APP_APIURL,
headers:{
"Content-type":"application/json"
}
})
超时时间
一个请求超过一段时间自动停止。
// 设置超时时间
timeout: 10000,
request 拦截器
在请求发出之前,抽离出共同的方法。
例如 对于所有的psot请求,我们可能需要去进行序列化参数(后端要求序列化的参数),
又例如,我们发送的请求是错误的,我们要如何处理。
又又例如:我们的请求接口是需要token的,但是登录的接口不需要,此时我们在请求时就需要拦截,给除了登录接口之外的其他接口加上token。
参考官网的写法http://axios-js.com/zh-cn/docs/index.html#%E6%8B%A6%E6%88%AA%E5%99%A8
axiosInstance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
console.log("我是请求拦截器")
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
response 拦截器
在接收到请求之后,抽离出共同的方法。
例如: 接口400怎么办,接口500怎么办!
又例如 :接收到的数据怎么办!
axiosInstance.interceptors.response.use(function (response) {
let data;
// IE9时response.data是undefined,因此需要使用response.request.responseText(Stringify后的字符串)
if (response.data == undefined) {
data = response.request.responseText
} else {
data = response.data
}
// 对响应数据做点什么
return data;
}, function (err) {
console.log("接收到结果")
if (err && err.response) {
console.log(err.response.status)
switch (err.response.status) {
case 400:
err.message = '请求错误'
break
case 401:
err.message = '未授权,请登录'
break
case 403:
err.message = '拒绝访问'
break
case 404:
err.message = `请求地址出错: ${err.response.config.url}`
break
case 408:
err.message = '请求超时'
break
case 500:
err.message = '服务器内部错误'
break
case 501:
err.message = '服务未实现'
break
case 502:
err.message = '网关错误'
break
case 503:
err.message = '服务不可用'
break
case 504:
err.message = '网关超时'
break
case 505:
err.message = 'HTTP版本不受支持'
break
default:
}
}
// 对响应错误做点什么
return Promise.reject(err);
});
统一Api管理
对于同一个模块的请求我们通常是放在封装在一个文件夹里。例如这里的课程管理,我会新建src\api\TutorialDataApi.js
文件。
在这个文件里,编写涉及到可册灰姑娘的增删改查接口。
例如我们上节课程的新增接口。
import axiosUtil from '../utils/axiosUtil.js'
class TutorialDataApi{
create(data){
console.log(data)
return axiosUtil.post('/tutorials',data)
}
delete(data){
。。。。。。。
}
}
export default new TutorialDataApi();
使用
在src\views\AddTutorial.vue
我们重写Submit方法。
TutorialDataApi.create(tutorial).then((res)=>{
console.log(res)
},err=>{
console.log(err)
})
- 点赞
- 收藏
- 关注作者
评论(0)