Axios介绍
1、Axios是什么?
- Axios是一个基于promise的HTTP库,类似于jQuery的ajax,用于http请求。可以应用于浏览器端和node.js,既可以用于客户端,也可以用于node.js编写的服务端。
2、Axios特性
- (1)支持Promise API
- (2)拦截请求与响应,比如:在请求前添加授权和响应前做一些事情。
- (3)转换请求数据和响应数据,比如:进行请求加密或者响应数据加密。
- (4)取消请求
- (5)自动转换JSON数据
- (6)客户端支持防御XSRF
3、浏览器支持情况
- Firefox、Chrome、Safari、Opera、Edge、IE8+
Axios使用
vue创建项目 vue create axios-vue,选择自定义配置manually select features,终端显示如下:上下键切换,空格键选择对应配置。
而后,我们一次选择一下配置:
运行终端指令 cd axios-vue 、npm run serve启动项目后,运行终端指令npm add axios安装axios,至此,项目创建完成,axios安装完成。
在项目的public文件夹下新建data.json文件,用于模拟数据。在组建中引入axios,并发起请求。
{
"title":"vue project",
"create_time":"2019-01-01"
}
在组件中中,引入axios并使用。
import axios from "axios"
axios.get("/data.json").then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
此时,已经可以请求掉数据了,效果如下:
axios常用的请求方法
方法列举:get, post, put, patch, delete
- get:一般用户获取数据
- post:一般用于表单提交与文件上传
- patch:更新数据(只将修改的数据推送到后端)
- put:更新数据(所有数据推送到服务端)
- delete:删除数据
备注:post一般用于新建数据,put一般用于更新数据,patch一般用于数据量较大的时候的数据更新。
get方法
- 方式一
如果不带有参数,代码如下:
axios
.get("/data.json")
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
如果带有参数,代码如下:
axios
.get("/data.json", {
params: {
id: 12
}
})
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
此时表示,参数为id=12,最终的请求路径Request URL: http://localhost:8080/data.json?id=12
- 方式二
如果不带参数,代码如下:
axios({
method:'get',
url:'/data.json'
}).then(res=>{
console.log(res)
})
如果带有参数,代码如下:
axios({
method: "get",
url: "/data.json",
params:{
id:12
}
}).then(res => {
console.log(res);
});
此时表示,参数为id=12,最终的请求路径Request URL:http://localhost:8080/data.json?id=12
浏览器控制台相关信息介绍:
- Request URL:请求URL
- Request Method:请求方式
post方法
post请求常用的数据请求格式有两种:
form-data(常用于表单提交(图片上传、文件上传))
let data = {
id: 12
};
let formData = new FormData();
for(let key in data){
formData.append(key,data[key])
}
console.log(formData)
axios.post('/data.json',formData).then(res=>{
console.log(res,'formData')
})
注意:请求地址Request URL: http://192.168.1.106:8080/data.json,
请求头中Content-Type: multipart/form-data; boundary=----WebKitFormBoundarydgohzXGsZdFwS16Y
参数形式:id:12
application/json(常用)
- 方式一
let data = {
id: 12
};
axios.post("/data.json", data).then(res=>{
console.log(res, 'post')
});
- 方式二
let data = {
id: 12
};
axios({
method:'post',
url:'/data.json',
data:data
}).then(res=>{
console.log(res)
})
注意:请求地址Request URL: http://192.168.1.106:8080/data.json,
请求头中Content-Type: application/json;charset=UTF-8
参数形式:{id:12}
put方法
let data = {
id: 12
};
axios.put("/data.json", data).then(res=>{
console.log(res, 'put')
});
patch方法
let data = {
id: 12
};
axios.patch("/data.json", data).then(res=>{
console.log(res, 'patch')
});
备注:put与patch与post方法只有method不同,其他相同。
delete方法
- 方式一:params
axios
.delete("/data.json", {
params: {
id: 12
}
})
.then(res => {
console.log(res, "delete");
});
let params = {
id: 12
};
axios({
method:'delete',
url:'/data.json',
params:params
}).then(res=>{
console.log(res)
})
- 方式二:data
axios
.delete("/data.json", {
data: {
id: 12
}
})
.then(res => {
console.log(res, "delete");
});
let data = {
id: 12
};
axios({
method:'delete',
url:'/data.json',
data:data
}).then(res=>{
console.log(res)
})
注意:params方式会将请求参数拼接在URL上面,Request URL: http://192.168.1.106:8080/data.json?id=12
参数形式:id:12
Content-Type: text/html; charset=utf-8
data方式不会讲参数拼接,是直接放置在请求体中的,Request URL:http://192.168.1.106:8080/data.json
参数形式:{id:12}
Content-Type: application/json;charset=UTF-8
总结:上述方法中均对应两种写法:(1)使用别名:形如axios.get();(2)不使用别名形如axios();
并发请求
并发请求,就是同时进行多个请求,并统一处理返回值。
在例子中,我们使用axios.all,对data.json/city.json同时进行请求,使用axios.spread,对返回的结果分别进行处理。代码如下:
// 并发请求
axios.all([axios.get("/data.json"), axios.get("/city.json")]).then(
axios.spread((dataRes, cityRes) => {
console.log(dataRes, cityRes);
})
);
注意:axios.all的参数是请求函数的数组,在对应的回调then中,调用axios.spead对返回值进行处理,即可。
并发请求的应用场景:需要同时进行多个请求,并且需要同时处理接口调用的返回值的时候,我们可以使用并发请求。
axios实例的创建
比如:后端接口地址有多个(www.test.com、www.example.com),并且超时时长不同(1000ms、2000ms),这个时候,我们可以创建实例。
思路如下:创建多个实例,配置不同的超时时长,用不同的实例去请求不同的接口。使用axios.acreate来创建实例,配置相关信息,进行网络请求。代码如下:
// 实例1
let instance = axios.create({
baseURL:'http://loacalhost:8080',
timeout:1000
})
instance.get('/data.json').then(res=>{
console.log(res)
})
//实例2
let instance2 = axios.create({
baseURL: "http://loacalhost:8081",
timeout: 2000
});
instance2.get("/city.json").then(res => {
console.log(res);
});
备注:此时我们就可以访问http://loacalhost:8080与http://loacalhost:8081两个不同域名的接口,并且使用不同的配置。
axios实例的相关配置
(1)配置列表
- baseURL:请求的域名(基本地址)。
- timeout:请求的超时时长,超出后后端返回401。
- 备注:一般由后端定义,后端的接口需要的处理时长较长的时候,如果请求的时间过长,后端处理不过来,就会阻塞,给服务器造成较大的压力。设置后,可以及时释放掉。
- url:请求路径。
- method:请求方法。如:get、post、put、patch、delete等。
- headers:请求头。
- params:将请求参数拼接到url上
- data:将请求参数放置到请求体里
axios.create({
baseURL:'', //请求的域名(基本地址)
timeout:2000, //请求的超时时长,单位毫秒,默认。
url:'/data.json', //请求路径
method:'get', //请求方法
headers:{
token:''
}, //设置请求头
params:{
},//将请求参数拼接到url上
data:{
}, //将请求参数放置到请求体里
});
三种配置方式:
- axios全局配置
axios.defaults.baseURL = 'http://localhost:8080'
axios.defaults.timeout = 2000
- axios实例配置
let instance = axios.create();
instance.defaults.timeout = 3000
- axios请求配置
instance.get('/data.json',{
timeout:5000
})
优先级:axios全局配置 < axios实例配置 < axios请求配置
常用参数配置的使用方法
- 举例1:
let instance1 = axios.create({
baseURL:'http://localhost:9090',
timeout:1000
})
instance1.get("/contactList",{
params:{
id:10
}
}).then(res=>{
console.log(res)
})
分析:配置的参数为baseURL:‘http://localhost:9090’,timeout:1000,method:‘get’,params:{ id:10},url:’/contactList’
- 举例2:
let instance2 = axios.create({
baseURL:'http://localhost:9091',
timeout:3000
})
instance2.get("/contactList",{
timeout:5000
}).then(res=>{
console.log(res)
})
分析:配置的参数为baseURL:‘http://localhost:9091’,timeout:5000,method:‘get’,url:’/contactList’
注意:最终的有效配置是由优先级高的覆盖优先级低的。
拦截器
什么拦截器?
在请求前或响应被处理前拦截他们,分为两种:请求拦截器与响应拦截器
拦截器的使用方法
- 请求拦截器
// 请求拦截器
axios.interceptors.request.use(config => {
// 在发送请求前做些什么
return config;
}, err=>{
// 在请求错误的时候的逻辑处理
return Promise.reject(err)
});
- 响应拦截器
// 响应拦截器
axios.interceptors.response.use(res => {
// 在请求成功后的数据处理
return res;
}, err=>{
// 在响应错误的时候的逻辑处理
return Promise.reject(err)
});
- 取消拦截器
let inter = axios.interceptors.request.use(config=>{
config.header={
auth:true
}
return config
})
axios.interceptors.request.eject(inter)
实用举例A:登录权限
需要token的接口实例
// 需要token的接口
let instance = axios.create({});
instance.interceptors.request.use(config=>{
config.headers.token = '';
return config
})
不需要token的接口实例
// 不需要token接口
let newInstance = axios.create({});
实用举例B:移动端开发数据加载loading动画
// 请求的加载动画loading
let instance_phone = axios.create({});
instance_phone.interceptors.request.use(config=>{
$('#loading').show();
return config
})
instance_phone.interceptors.response.use(res=>{
$('#loading').hide();
return res
})
备注:实现的效果是请求数据的时候显示loading动画,数据响应后隐藏loading动画。
错误处理
结合请求拦截器与响应拦截器来说,不管是请求错误还是响应错误,都会执行catch方法。
// 请求拦截器
axios.interceptors.request.use(
config => {
// 在发送请求前做些什么
return config;
},
err => {
// 在请求错误的时候的逻辑处理
return Promise.reject(err);
}
);
// 响应拦截器
axios.interceptors.response.use(
res => {
// 在请求成功后的数据处理
return res;
},
err => {
// 在响应错误的时候的逻辑处理
return Promise.reject(err);
}
);
axios
.get("data.json")
.then(res => {
console.log(res);
})
.catch(err => {
console.log(res);
});
错误处理举例
在实际开发中,不会再每次网络请求的时候,都使用catch方法,可以添加统一的错误处理方法。代码如下:
// 请求错误处理
let instance = axios.create({});
instance.interceptors.request.use(
config => {
return config;
},
err => {
// 请求错误的常见状态码:4XX 401-请求超时 404-mot found
$("#error").show();
setTimeout(()=>{
$("#error").hide();
}, 2000)
return Promise.reject(err);
}
);
// 响应错误处理
instance.interceptors.response.use(
res => {
return res;
},
err => {
// 响应错误的常见状态码 5XX 500-服务器错误 502-服务器重启
$("#error").show();
setTimeout(()=>{
$("#error").hide();
}, 2000)
return Promise.reject(err);
}
);
instance.get("/data.json").then(res=>{
console.log(res,'请求成功')
}).catch(err=>{
console.log(err,'除了拦截器设置的处理之外的其他处理')
})
思路分析:首先创建实例,给实例设置请求拦截器与响应拦截器。
- (1)请求错误的常见状态码以4开头,如401-请求超时、404-接口未找到;
- (2)响应错误的常见状态码以5开头,如500-服务器错误、502-服务器重启等。
- (3)处理设置请求拦截器与响应拦截器的操作外,如果还要其他操作,我们可以在请求的时候,在使用catch方法。
取消请求(不常用)
- 代码示例
let source = axios.CancelToken.source();
axios
.get("/data.json", {
cancelToken: source.token
})
.then(res => {
console.log(res);
}).catch(err=>{
console.log(err)
})
// 取消请求(参数msg)
source.cancel('自定的的字符串可选')
- 应用场景
在查询数据的时候,很长时间(3-5s)仍未获取数据,这个时候需要取消请求。
代理
vue cil2
代理分为旧版本 也就是 vue cil2 这个版本需要在config/index.js下配置
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
// 后端请求地址代理,配置后testIp再之后的页面调用时就直接指代 http://197.82.15.15:8088
proxyTable: {
'/testIp': {
target: 'http://197.82.15.15:8088',
changeOrigin: true,
pathRewrite: {
'^/testIp': ''
}
},
'/elseIp': {
target: 'http://182.83.19.15:8080',
changeOrigin: true,
pathRewrite: {
'^/esleIp': ''
}
},
},
-----------------------------------------------------------
vue cil 3在 vue.config.js文件下
devServer: {
overlay: { // 让浏览器 overlay 同时显示警告和错误
warnings: true,
errors: true
},
host: "localhost",
port: 8080, // 端口号
https: false, // https:{type:Boolean}
open: false, //配置后自动启动浏览器
hotOnly: true, // 热更新
// proxy: 'http://localhost:8080' // 配置跨域处理,只有一个代理
proxy: { //配置多个代理
"/testIp": {
target: "http://197.0.0.1:8088",
changeOrigin: true,
ws: true,//websocket支持
secure: false,
pathRewrite: {
"^/testIp": "/"
}
},
"/elseIp": {
target: "http://197.0.0.2:8088",
changeOrigin: true,
//ws: true,//websocket支持
secure: false,
pathRewrite: {
"^/elseIp": "/"
}
},
}
}
当项目有多个后台的时候,可以在api文件夹下 新建一个elseApi.js ,书写当前ip下的接口请求。方法同上,只是 `let resquest = "/elseIp/request/"` 调用的时候把端口更改一下。
request.js
在项目src目录下新建utils文件夹,然后在其中新建 request.js文件,这个文件是主要书写axios的封装过程。
/**** request.js ****/
// 导入axios
import axios from 'axios'
// 使用element-ui Message做消息提醒
import { Message} from 'element-ui';
//1. 创建新的axios实例,
const service = axios.create({
// 公共接口--webpack中的全局变量process.env.BASE_API
//为了适应多个后台或者开发的时候的api地址和发布的时候的api地址不一样这种情况
baseURL: process.env.BASE_API,
// 超时时间 单位是ms,这里设置了3s的超时时间
timeout: 3 * 1000
})
// 2.请求拦截器
service.interceptors.request.use(config => {
//发请求前做的一些处理,数据转化,配置请求头,设置token,设置loading等,根据需求去添加
***** 下面详解
config.data = JSON.stringify(config.data); //数据转化,也可以使用qs转换
config.headers = {
'Content-Type':'application/x-www-form-urlencoded' //配置请求头
}
//注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookie
const token = getCookie('名称');//这里取token之前,你肯定需要先拿到token,存一下
if(token){
config.params = {'token':token} //如果要求携带在参数中
config.headers.token= token; //如果要求携带在请求头中
}
*****
return config
}, error => {
Promise.reject(error)
})
// 3.响应拦截器
service.interceptors.response.use(response => {
//接收到响应数据并成功后的一些共有的处理,关闭loading等
return response
}, error => {
/***** 接收到异常响应的处理开始 *****/
if (error && error.response) {
// 1.公共错误处理
// 2.根据响应码具体处理
switch (error.response.status) {
case 400:
error.message = '错误请求'
break;
case 401:
error.message = '未授权,请重新登录'
break;
case 403:
error.message = '拒绝访问'
break;
case 404:
error.message = '请求错误,未找到该资源'
window.location.href = "/NotFound"
break;
case 405:
error.message = '请求方法未允许'
break;
case 408:
error.message = '请求超时'
break;
case 500:
error.message = '服务器端出错'
break;
case 501:
error.message = '网络未实现'
break;
case 502:
error.message = '网络错误'
break;
case 503:
error.message = '服务不可用'
break;
case 504:
error.message = '网络超时'
break;
case 505:
error.message = 'http版本不支持该请求'
break;
default:
error.message = `连接错误${error.response.status}`
}
} else {
// 超时处理
if (JSON.stringify(error).includes('timeout')) {
Message.error('服务器响应超时,请刷新当前页')
}
error.message('连接服务器失败')
}
Message.error(error.message)
/***** 处理结束 *****/
//如果不需要错误处理,以上的处理过程都可省略
return Promise.resolve(error.response)
})
//4.导入文件
export default service0
数据转换说明
config.data = JSON.stringify(config.data);
config.headers = { 'Content-Type':'application/x-www-form-urlencoded' }
const token = getCookie('名称')
if(token){
config.params = {'token':token} ;
config.headers.token= token;
}
上述的代码都是请求的配置项,非必须,也是分情况的,data/headers/params 这种本身的参数都有多种,和后台沟通,需要什么就配什么!
config.data = JSON.stringify(config.data);为什么不用qs.stringify,因为我的后台想要的只是json类型的传参,而qs转换会转换成为键值对拼接的字符串形式。当然你们后台需要传递字符串类型参数,那就换成qs或者其他格式方式。
const token = getCookie('名称')这是token的取值,在取之前你肯定需要发请求拿到token,然后setCookie存起来,而名称就是你存的token的名称,每个人的不一样;
config.headers = { 'Content-Type':'application/x-www-form-urlencoded' }请求头内容的配置,也是不同的,application/x-www-form-urlencoded :form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式),你可以根据实际情况去配置自己需要的;
以上
我已经举了很清晰的例子,写代码的过程是自己动脑去搭建工程的,希望能看到我文章的各位,善于搜索,善于思考,善于总结;
当然我很喜欢帮大家解决问题,但是相关的基础问题,还是建议自己去学习掌握。
Axios中的http.js
在项目src目录下的utils文件夹中新建 http.js文件,这个文件是主要书写几种请求的封装过程。
/**** http.js ****/
// 导入封装好的axios实例
import request from './request'
const http ={
/**
* methods: 请求
* @param url 请求地址
* @param params 请求参数
*/
get(url,params){
const config = {
method: 'get',
url:url
}
if(params) config.params = params
return request(config)
},
post(url,params){
const config = {
method: 'post',
url:url
}
if(params) config.data = params
return request(config)
},
put(url,params){
const config = {
method: 'put',
url:url
}
if(params) config.params = params
return request(config)
},
delete(url,params){
const config = {
method: 'delete',
url:url
}
if(params) config.params = params
return request(config)
}
}
//导出
export default http
Axios中的api.js
在项目src目录下新建api文件夹,然后在其中新建 api.js文件,这个文件是主要书写API的封装过程。
当一个项目中后台请求不是同一个IP地址,是多个IP地址的时候,可以在api文件夹下创建多个js文件,用来调用请求
api.js有两种导出方式,分类导出和全部导出
分类导出
import http from '../utils/http'
//
/**
* @params resquest 请求地址 例如:http://197.82.15.15:8088/request/...
* @param '/testIp'代表vue-cil中config,index.js中配置的代理
*/
let resquest = "/testIp/request/"
// get请求
export function getListAPI(params){
return http.get(`${resquest}/getList.json`,params)
}
// post请求
export function postFormAPI(params){
return http.post(`${resquest}/postForm.json`,params)
}
// put 请求
export function putSomeAPI(params){
return http.put(`${resquest}/putSome.json`,params)
}
// delete 请求
export function deleteListAPI(params){
return http.delete(`${resquest}/deleteList.json`,params)
}
---------------------------------------------------
全部导出
import http from '../utils/http'
//
/**
* @params resquest 请求地址 例如:http://197.82.15.15:8088/request/...
* @param '/testIp'代表vue-cil中config,index.js中配置的代理
*/
let resquest = "/testIp/request/"
// get请求
export default{
getListAPI(params){
return http.get(`${resquest}/getList.json`,params)
},
postFormAPI(params){
return http.post(`${resquest}/postForm.json`,params)
}
}
———————————————————————————————————————————————————
以上封装完毕接下来我们看如何调用
在Vue中调用接口
用到哪个api 就调用哪个接口——适用于上文接口分类导出;
import {getListAPI,postFormAPI, putSomeAPI, deleteListAPI} from '@/api/api'
methods: {
//promise调用,链式调用, getList()括号内只接受参数;
// get不传参
getList() {
getListAPI().then(res => console.log(res)).catch(err => console.log(err))
},
//post传参
postForm(formData) {
let data = formData
postFormAPI(data).then(res => console.log(res)).catch(err => console.log(err))
},
//async await同步调用
async postForm(formData) {
const postRes = await postFormAPI(formData)
const putRes = await putSomeAPI({data: 'putTest'})
const deleteRes = await deleteListAPI(formData.name)
// 数据处理
console.log(postRes);
console.log(putRes);
console.log(deleteRes);
},
}
-----------------------------------------------
把api全部导入,然后用哪个调用哪个api——适用于全部导出
import api from '@/api/api'
methods: {
getList() {
api.getListAPI(data).then(res => {
//数据处理
}).catch(err => console.log(err))
}
}