axios
Ajax、fetch、axios的区别与优缺点
axios源码深度剖析
axios内部的运作流程图
一、直接用封装好的vue-axios(我不推荐使用,感觉还是有点难用)
安装
npm install --save axios vue-axios
将下面代码加入main.js入口文件:
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.prototype.$axios = axios //全局注册,使用方法为:this.$axios
Vue.use(VueAxios, axios)
在页面中使用它
<script>
export default{
data(){
return{
token:"token"
}
},
created(){
this.$axios({
method:'post',
url:'api',
data:{
//这里是发送给后台的数据
token:this.token
}
}).then((response) =>{
console.log(response) //请求成功返回的数据
}).catch((error) =>{
console.log(error) //请求失败返回的数据
})
}
}
</script>
二、自己封装的axios
axios 是一个基于 Promise 的http请求库, 它支持浏览器和node.js以及promise,能拦截请求和响应,也能取消请求,而且可以自动转换JSON数据,浏览器端支持防止CSRF(跨站请求伪造)等等。
1、安装
npm install axios; // 安装axios
2、在项目目录下引入axios
我通常习惯在src根目录下创建一个request文件夹(这是当时做后台管理系统的时候学来的),在request文件夹里创建api.js用来管理封装接口,创建axios.js用来封装axios。到时候随着后台接口的增多和模块化,可以根据不同的模块创建不同的js文件或者文件夹便于管理api。
- 下面是我总结的常用的一个
axios.js
文件的封装,注释部分需要结合自身实际情况修改
1、baseURL
2、请求拦截器,例如请求的时候在头部加上请求的token
3、响应拦截器,例如判断状态,过期清除token
import axios from 'axios';
// 让请求在浏览器中允许跨域携带cookie
axios.defaults.withCredentials = true;
// 使用自定义配置新建一个 axios 实例
const service= axios.create({
// 基础的请求地址
baseURL: 'https://some-domain.com/api/',
// 设置超时时间 5s
timeout: 5000
});
// 添加超时后的处理(axios中需要你根据error信息来进行判断)
axios().catch(error => {
const { message } = error;
if (error.code === 'ECONNABORTED' && message.indexOf('timeout')> -1){
// 超时处理,可以直接弹出错误或者重新发起一次请求
alert("请求超时!请检查网络问题");
// let newHttp= new Promise(function (resolve){
// resolve()
// })
// newHttp实例执行完成后会再次执行
// 返回一个promise实例,同时重新发起请求,config请求配置,包扩请求头和请求参数
// return newHttp.then(function (){
// return axios.create({baseURL: 'https://some-domain.com/api/',timeout: 5000});
// })
}
// 若不是超时,则返回未错误信息
return Promise.reject(error);
})
// 请求拦截器,例如请求的时候在头部加上请求的token
service.interceptors.request.use(config => {
// if (localStorage.getItem('token')) {
// config.headers.ACCESS_TOKEN = localStorage.getItem('token');
// }
return config; // 有且必须有一个config对象被返回
}, error => {
// 对请求错误做些什么
console.log(error);
return Promise.reject();
});
// 响应拦截器,例如判断服务器返回的状态,400,500啥的,其实超时可以写到这里面来,我分开写了一个比较直观
service.interceptors.response.use(
response => {
if (response.status === 200) {
return Promise.resolve(response.data);
} else {
return Promise.reject(response);
}
},
// 服务器状态码不是200的情况,这些自定义(需要与后台商量返回)
error => {
if (
400 <= error.response.status <500
) {
alert("用户信息过期,请重新登陆");
// 清除token
// localStorage.removeItem("token");
// 跳转登录
setTimeout(() => {
// window.location.href = "/login";
}, 1000);
} else {
if (error.response.status >= 500) {
alert("服务器开小差了,请稍后再试!");
} else {
alert("服务器开小差了,请稍后再试!");
return Promise.reject(error)
}
}
}
);
export default service;
- 下面是我
api.js
接口文件的管理,需要结合自身实际情况修改
1、url :请求接口的地址(就是baseURL后面的哪部分)
2、method:请求方法
3、data:post请求中携带的数据(obj格式),params:get请求中携带的数据(就是在浏览器地址xx/xx/xx后面?XX=oo&XX=oo这部分数据,obj格式)
4、传过来的参数一定要在(query)=>{ }
括号中引入,函数里面才能用
// 刚刚封装的axios
import request from './axios';
// 1.获取图片验证码
export const getImgCode = () => {
return request({
url: '/image/code',
method: 'get',
// 图片验证码 response类型设置成blob,图片才能显示出来
responseType: "blob"
})
}
// 2.获取手机验证码
export const getPhoneCode = (query) => {
return request({
url: '/user/messageCode',
method: 'post',
data: query
})
}
// 3. 获取用户任务列表
export const getUserTask = (query) => {
return request({
url: '/task/select',
method: 'get',
params: query
})
}
// 4. 搜索任务接口
export const queryTask = (query1, query2) => {
return request({
url: '/task/query',
method: 'post',
data: query1,
params: query2
})
}
- 在
xx.vue
页面中的实际操作
1、<script>标签顶部将刚刚封装的api引入import { getImgCode, getUserTask } from "../request/api";
2、方法使用:getImgCode().then(res=>{}).catch(res=>{})
3、下面提供了登陆时候做图片验证码的一个操作
<template>
<div>
<div class="code">
<img class="codeimg" :src="this.ImgCode" @click="getCode" alt />
<input type="text" name="验证码" placeholder="验证码" v-model="code" />
</div>
</div>
</template>
<script>
import { getImgCode, getUserTask } from "../request/api";
export default {
data() {
return { ImgCode: "", phone: "", password: "", code: "" };
},
mounted() {
// 初始化页面之前获取图片验证码的接口,无需定义方法直接请求
getImgCode()
.then(res => {
let blob = new Blob([res], { type: "image/jpeg" });
let url = URL.createObjectURL(blob);
this.ImgCode = url;
})
.catch(res => {
alert("网络开小差了,没有获取到图片验证码哦");
});
},
methods: {
// 先定义一个方法 getCode,供上面引用,
getCode() {
// 传得参数对象
let query = {
a:this.phone,
b:this.password
}
// 请求刚刚引入的封装的接口
getUserTask (query)
.then(res => {
// 成功之后的操作
})
.catch(res => {
// 失败时候的操作
});
}
}
};
</script>
<style scoped>
</style>
三、使用总结
- 封装axios供之后引用,将
baseURL
,请求拦截器
,响应拦截器
结合实际情况与vuex一起封装 - 在封装api接口文件中引用刚刚封装的axios,把
接口url
和请求方法method
和参数(data/params)
定义到每个接口函数中并暴露出来 - 在后缀为
.vue
的文件中引入api接口文件中需要的接口import { getImgCode, getUserTask } from "../request/api";
- 在需要的地方使用
getImgCode().then(res=>{}).catch(res=>{})
四、axios优点(特性)
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
1. 从浏览器中创建 XMLHttpRequests
2. 从 node.js 创建 http 请求
3. 支持 Promise API
4. 拦截请求和响应
5. 转换请求数据和响应数据
6. 取消请求
7. 自动转换 JSON 数据
8. 客户端支持防御 XSRF
9. 浏览器支持
五、源码分析
上面那篇文章Axios源码深度剖析已经很详细,我想谈谈我的看法。
TODO