axios简介
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
axios是我们在vue项目中常见封装http请求相对受欢迎的,优点如下:
简单易用,api接近于jquery,比原生的fetch之类的简单,
浏览器兼容性好,都能兼容IE7,使用fetch就得自己处理兼容
通用性好,能在node和浏览器中使用
api一致 稳定大牌,vue官网文档有推荐
以上几点呢,是大多数公司选择使用axios的主要原因,通过简单的了解我们应该知道axios是干嘛的了,请求这里指的是数据的传输,web端http属于单向的,你问了他就告诉你,服务端不会主动告诉你,这个就叫http请求,因为有协议的原因,所以这里很多人还是不能熟练掌握,具体请求具体传参,所以我准备专门介绍一下,各请求之间我是如何判断该何如传参的:
先说一下request 他是一个任意类型的请求,你在mehod: ‘请求别名’ 比如:get post 都可以
get 向指定资源请求数据,一般用来获取,查询资源信息,较不安全,幂等(幂等是对同一URL的多个请求应该返回同样的结果)的,只用来获取数据不会修改数据,其请求显示在url上,会被缓存,对请求长度有限制。和post是常用的提交方式。
delete 请求服务器器删除Request-URI所标识的资源。
head是需要向服务器索要与get一样的请求,但是不返回返回体,这个方法可以在不必传输整个响应内容的情况下,获取包含在响应消息头中的元信息。
option返回给服务器针对特定资源所支持的请求方式,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性。
post 向指定资源提交数据进行请求处理,一般用来更新资源信息,非幂等,请求显示在请求体里面,不会被缓存,对请求长度无限制。
put 向指定资源上传最新的内容
patch方法用来更新部分资源,然而PATCH和POST都是非幂等的,POST请求服务器执行一个动作,多次请求会多次执行。PATCH提供的实体则需要根据程序或其它协议的定义,解析后在服务器上执行,以此来修改服务器上的数据。也就是说,PATCH请求是会执行某个程序的,如果重复提交,程序可能执行多次,对服务器上的资源就可能造成额外的影响POST方法和PATCH方法它们的实体部分都是结构化的数据,所以PAtch也是非幂等的。POST方法的实体结构一般是 multipart/form-data或 application/x-www-form-urlencoded而PATCH方法的实体结构则随其它规范定义。这和PUT方法的无结构实体相比就是最大的区别。
axios 默认配置
axios.defaults.baseURL="http://localhost:8888/";
axios.defaults.timeout=4000;
axios get请求
//get请求方式一:
axios({
// 默认请求方式为get
method: 'get',
url: 'api',
// 传递参数
params: {
key: value
},
// 设置请求头信息
headers: {
key: value
}
responseType: 'json'
}).then((response) => {
// 请求成功
let res = response.data;
console.log(res);
}).catch((error) => {
// 请求失败,
console.log(error);
});
//get请求方式二:
axios.get("api", {
// 传递参数
params: {
key: value
},
// 设置请求头信息,可以传递空值
headers: {
key: value
}
}).then((response) => {
// 请求成功
let res = response.data;
console.log(res);
}).catch(error => {
// 请求失败,
console.log(error);
});
axios post请求
//post普通方式:
axios({
method: 'post',
url: 'api',
// 传递参数
data,
// 设置请求头信息
headers: {
key: value
},
responseType: 'json'
}).then((response )=> {
// 请求成功
let res = response.data;
console.log(res);
}).catch(error => {
// 请求失败,
console.log(error);
});
//post别名的方式:---注意post传参的key是data,get的是params
let headers = {
TOKEN: ""
};
axios.post("api", data, {headers}}).then((response) => {
// 请求成功
let res = response.data;
console.log(res);
}).catch((error) => {
// 请求失败,
console.log(error);
});
axios发送并发请求
//方法一:请求成功时响应的是一个数组
axios.all([
axios.get('http://localhost:8888/info'),
axios.get('http://localhost:8888/infos')
]).then((res) => {
console.log(res[0]); //第一个axios请求得到的
console.log(res[1]); //第二个axios请求得到的
}).catch((err) => {
console.log(err);
})
//采用axios提供的spread函数处理响应数组结果
axios.all([
axios.get('http://localhost:8888/info'),
axios.get('http://localhost:8888/infos')
]).then(axios.spread((res1,res2) =>{
console.log(res1); //第一个axios请求得到的
console.log(res2); //第二个axios请求得到的
})).catch((err) => {
console.log(err);
})
axios 封装
例一:
// 对axios的一次封装
import axio from 'axios'
import store from '../store'
import { removeItem } from '../utils/localStorage'
import { Toast } from 'vant'
import router from '@/router'
Toast.setDefaultOptions({ forbidClick: true })
const axios = axio.create({
baseURL: 'http://123.60.80.68:8100/',
// baseURL: 'http://192.168.0.231:8080/',
timeout: 30000
})
// 请求拦截器,实现token的统一添加;
axios.interceptors.request.use(
config => {
if (store.state.token) {
config.headers.accessToken = store.state.token
}
return config
}, err => {
return Promise.reject(err)
})
axios.interceptors.response.use(
response => {
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
// 否则的话抛出错误
if (response.status === 200) {
return Promise.resolve(response.data)
} else {
return Promise.reject(new Error(res.message || 'Error'))
}
},
// 服务器状态码不是2开头的的情况
// 这里可以跟你们的后台开发人员协商好统一的错误状态码
// 然后根据返回的状态码进行一些操作,例如登录过期提示,错误提示等等
// 下面列举几个常见的操作,其他需求可自行扩展
error => {
if (error.response.data.status) {
switch (error.response.data.status) {
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
router.replace({
path: '/login'
})
break
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 6001:
Toast({
message: '登录过期,请重新登录',
duration: 1000,
forbidClick: true
})
// 清除token
removeItem('user')
store.commit('setUser', null)
store.commit('setToken', '')
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => {
router.replace({
path: '/login'
})
}, 1000)
break
// 404请求不存在
case 404:
Toast({
message: '网络请求不存在',
duration: 1500,
forbidClick: true
})
break
// 其他错误,直接抛出错误提示
default:
Toast({
message: error.response.data.message,
duration: 1000,
forbidClick: true
})
}
}
return Promise.reject(error.response.data.message)
})
export default axios
例二:
import axios from 'axios'
let baseURL;
if(process.env.NODE_ENV === 'development') {
baseURL = 'xxx本地环境xxx';
} else if(process.env.NODE_ENV === 'production') {
baseURL = 'xxx生产环境xxx';
}
// 实例
let instance = axios.create({
baseURL: baseURL,
...
})
//设置axios拦截器: 请求拦截器
axios_instance.interceptors.request.use(config => {
//得到请求方式和请求体数据
const {method,data} = config;
if(method.toLowerCase() == 'post' && typeof data == 'object'){
config.data = qs.stringify(data)
}
config.headers['X-Token'] = getToken()
return config;
}, err => {
// 请求未成功发出,如:没有网络...
return Promise.reject(err)
})
//设置axios拦截器: 响应拦截器
axios_instance.interceptors.response.use(res => {
// 成功响应的拦截
const data = res.data;
const code = data.code;
if(code == 200 ){
return data;
}else{
return Promise.reject(data);
}
}, err =>{
//请求的地址错误 会进入这里
console.log(err)
return Promise.reject(err)
})
//接口的封装
import request from './requst'
/* 登录 */
export function login (data) {
return request({
url: '/login_auth/login',
method: 'get',
params: data
})
}
使用请求别名:
// 获取用户信息
export function getInfo () {
return request.get('/system/user/getLoginUser')
}