前言
本文将介绍axios的相关操作。
相关的后端服务器是用Flask搭建的,仅用于演示:
web.py
:
from flask import Flask,request
from flask_cors import CORS #引入CORS库
app = Flask(__name__)
CORS(app, supports_credentials=True) #用于解决跨域问题
@app.route("/")
if __name__=="__main__":
app.run()
说明:引入CORS库用于解决跨域问题。
以下的axios网络请求的代码都在Vue项目src
文件夹下的main.js
中完成。
这里也介绍一个网站,可以用于网络请求的测试:httpbin.org
axios
介绍
以下内容来自官网:axios中文文档|axios中文网 | axios (axios-js.com)
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
点击跳转 至 《Vue学习-Promise》
特性:
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
支持多种请求方式:
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[, config])
- axios.head(url[, config])
- axios.options(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.patch(url[, data[, config]])
基本使用
配置axios
打开终端,进入项目根目录,键入如下命令(注意版本号):
代码语言:javascript复制npm install axios --save
导入
在使用的文件头中导入:
代码语言:javascript复制import axios from 'axios'
发送GET/POST请求
main.js
:
import Vue from 'vue'
import App from './App'
import axios from 'axios'
Vue.config.productionTip = false
new Vue({
el: '#app',
render: h => h(App)
})
axios({
url: 'http://127.0.0.1:5000',
method: 'post',
params: {
name: 'HuaZhu',
age: 18
}
}).then((res) => {
console.log(res);
})
说明: (类似于ajax的使用方式) axios的参数需要传入一个对象,该对象有以下属性:
- url:用于指定请求的URL
- method:用于指定请求方式(
get
、post
),不写该参数默认使用get方式 - params:用于附带参数信息
值得注意的是axios已集成Promise,在发送请求后会自动执行resolve()
函数,因此可以在后面直接链接then()
函数,用于接收请求返回值。
web.py
:
from flask import Flask,request
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)
@app.route("/",methods=["GET","POST"])
def test():
if request.method=="GET":
name = request.args.get("name")
age = request.args.get("age")
print(name,age)
return "get请求已收到"
elif request.method=="POST":
name = request.values.get("name")
age = request.values.get("age")
print(name,age)
return "post请求已收到"
else:
return "网络请求方式不正确"
if __name__=="__main__":
app.run()
效果展示:
发送并发请求
如果需要向服务器同时发送多个并发请求,并取回每个请求的结果,然后对这些返回结果操作。axios提供了axios.all()
方法,使用格式如下:
axios.all([axios(), axios()], ...).then((results) => {...})
说明:
axios.all()
的参数为列表,里面可以写任意个axios()
方法- 最后
then()
获得的返回值同为列表形式,里面存放了每一个请求的结果
现在假设要向服务器同时发送get和post请求,并拿到返回值:
main.js
:
import Vue from 'vue'
import App from './App'
import axios from 'axios'
Vue.config.productionTip = false
new Vue({
el: '#app',
render: h => h(App)
})
axios.all([axios({
url: 'http://127.0.0.1:5000',
method: 'get', //发送get请求
params: {
name: 'HuaZhu',
age: 18
}
}), axios({
url: 'http://127.0.0.1:5000',
method: 'post', //发送post请求
params: {
name: 'HuaZhu',
age: 18
}
})]).then(results => {
console.log(results)
})
web.py
:
from flask import Flask,request
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)
@app.route("/",methods=["GET","POST"])
def test():
if request.method=="GET":
name = request.args.get("name")
age = request.args.get("age")
print(name,age)
return "get请求已收到"
elif request.method=="POST":
name = request.values.get("name")
age = request.values.get("age")
print(name,age)
return "post请求已收到"
else:
return "网络请求方式不正确"
if __name__=="__main__":
app.run()
效果展示:
返回结果列表拿到,如果要详细访问,可以通过列表的index下标值。但是axios还提供了axios.spread()
方法可以直接拆分返回结果列表,拿到具体的结果:
axios.all([axios({
url: 'http://127.0.0.1:5000',
method: 'get',
params: {
name: 'HuaZhu',
age: 18
}
}), axios({
url: 'http://127.0.0.1:5000',
method: 'post',
params: {
name: 'HuaZhu',
age: 18
}
})]).then(axios.spread((res1, res2) => {
console.log(res1);
console.log(res2);
}))
效果如下:
配置信息
基本配置
可以在axios对象中添加诸如baseURL
、timeout
等的配置信息:
axios({
baseURL: 'http://127.0.0.1:5000',
url: '/home',
timeout: 5000, //单位ms
method: 'post',
params: {
name: 'HuaZhu',
age: 18
}
}).then((res) => {
console.log(res);
})
全局配置
如果想在多个请求中使用同一配置,可以将这些配置信息抽离出来,设置全局默认配置:axios.defaults.xxx
axios.defaults.baseURL = 'http://127.0.0.1:5000'
axios.defaults.timeout = 5000
axios({
url: '/home',
method: 'post',
params: {
name: 'HuaZhu',
age: 18
}
}).then((res) => {
console.log(res);
})
axios实例
全局默认配置在项目规模较小的情况下(请求配置基本一致)可以使用,一旦涉及到的请求量增加,面临的情况可能是一类请求需要一种配置,另一类请求需要另外一种配置,如果这时再设置全局默认配置就不是很合适了。为此可以使用axios实例:axios.create()
const instance1 = axios.create({ //创建axios实例一
baseURL: 'http://127.0.0.1:5000',
timeout: 5000
})
instance1({ //使用axios实例一
url: '/home',
method: 'get',
}).then((res) => {
console.log(res);
})
instance1({ //使用axios实例一
url: '/about',
method: 'post',
}).then((res) => {
console.log(res);
})
const instance2 = axios.create({ //创建axios实例二
baseURL: 'http://127.0.0.1:8080',
timeout: 10000
})
instance2({ //使用axios实例二
url: '/home',
method: 'get',
}).then((res) => {
console.log(res);
})
instance2({ //使用axios实例二
url: '/about',
method: 'post',
}).then((res) => {
console.log(res);
})
常见的配置信息:
配置信息 | 格式 |
---|---|
请求地址 | url: ‘/home’ |
请求类型 | method: ‘get’ |
请求根路径 | baseURL: ‘http://127.0.0.1:5000’ |
请求前的数据处理 | transformRequest:[function(data){}] |
请求后的数据处理 | transformResponse: [function(data){}] |
自定义的请求头 | headers:{‘x-Requested-With’:‘XMLHttpRequest’} |
URL查询对象 | params:{ name: ‘HuaZhu’, age: 18 } |
查询对象序列化函数 | paramsSerializer: function(params){ } |
request body | data: { key: ‘a’} |
超时设置(ms) | timeout: 1000 |
跨域是否带Token | withCredentials: false |
自定义请求处理 | adapter: function(resolve, reject, config){} |
身份验证信息 | auth: { uname: ‘’, pwd: ‘12’} |
响应的数据格式 json / blob /document /arraybuffer / text / stream | responseType: ‘json’ |
axios封装
在大型项目中,往往第三方库在大量使用的情况下最好进行封装,在调用的时候只使用自己封装的内容就好。原因:如果第三方库停止维护,方便改用其他的代替内容。修改起来仅需改动封装的部分代码就好。
在项目的src
文件夹下新建一个network
文件夹,用于存放网络相关的封装代码。在其中新建名为axios-request.js
的文件:
import axios from 'axios'
export function axios_request(config) {
// 创建axios实例
const instance = axios.create({
baseURL: 'http://127.0.0.1:5000',
timeout: 5000
})
// 发送网络请求
return instance(config)
}
假设未来决定不再使用axios,改用其他的第三方库,如果该库也自动集成Promise,那调用格式同上,如果没有,那么就需要手动返回一个Promise对象: import xxx_request from 'xxx' export function xxx_request(config) { return new Promise((resolve, reject) => { // 1.调用xxx第三方库 // 2.发送请求 }) }
在其他文件中就可以直接调用封装的axios_request(config)
函数,其中config就是发送请求的配置信息:
main.js
:
import Vue from 'vue'
import App from './App'
import {axios_request} from './network/axios-request' //导入封装函数
Vue.config.productionTip = false
new Vue({
el: '#app',
render: h => h(App)
})
axios_request({ //使用封装函数
url: '/home',
method: 'post',
params: {
name: 'HuaZhu',
age: 18
}
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
})
说明: 由于
axios.create()
实例对象集成Promise,在调用时会自动执行resolve()
函数,因而可以在使用封装函数后直接调用then()
和catch()
函数。
web.py
:
from flask import Flask,request
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)
@app.route("/home",methods=["GET","POST"])
def test():
if request.method=="GET":
name = request.args.get("name")
age = request.args.get("age")
print(name,age)
return "get请求已收到"
elif request.method=="POST":
name = request.values.get("name")
age = request.values.get("age")
print(name,age)
return "post请求已收到"
else:
return "网络请求方式不正确"
if __name__=="__main__":
app.run()
拦截器
axios提供了拦截器,用于在发送每次请求或者从服务器得到返回结果时,进行相应的处理。
请求拦截
作用:
- 当发送网络请求时,在页面中添加一个loading组件,作为加载动画
- 某些请求要求用户必须登录,判断用户是否有token(令牌),如果没有则跳转到login页面
- 对请求的参数进行序列化
- …
格式: 局部拦截器:
instance.interceptors.request.use(onFulfilled(), onRejected())
全局拦截器:axios.interceptors.request.use(onFulfilled(), onRejected())
axios-request.js
:
import axios from 'axios'
export function axios_request(config) {
// 创建axios实例
const instance = axios.create({
baseURL: 'http://127.0.0.1:5000',
timeout: 5000
})
// 请求拦截器
instance.interceptors.request.use(config => {
console.log('成功拦截到请求');
console.log(config.params) //拦截成功后可以在此对config请求执行操作
return config //最后需要把拦截结果释放
}, err => {
console.log('拦截请求失败');
return err
})
// 发送网络请求
return instance(config)
}
main.js
:
import Vue from 'vue'
import App from './App'
import {axios_request} from './network/axios-request'
Vue.config.productionTip = false
new Vue({
el: '#app',
render: h => h(App)
})
axios_request({
url: '/home',
method: 'post',
params: {
name: 'HuaZhu',
age: 18
}
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
})
web.py
:
from flask import Flask,request
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)
@app.route("/home",methods=["GET","POST"])
def test():
if request.method=="GET":
name = request.args.get("name")
age = request.args.get("age")
print(name,age)
return "get请求已收到"
elif request.method=="POST":
name = request.values.get("name")
age = request.values.get("age")
print(name,age)
return "post请求已收到"
else:
return "网络请求方式不正确"
if __name__=="__main__":
app.run()
效果展示:
返回结果拦截
作用:
- 主要是对返回的结果进行过滤
- 相应失败后根据错误信息做出不同的响应
- …
格式: 局部拦截器:
instance.interceptors.response.use(onFulfilled(), onRejected())
全局拦截器:axios.interceptors.response.use(onFulfilled(), onRejected())
axios-request.js
:
import axios from 'axios'
export function axios_request(config) {
// 创建axios实例
const instance = axios.create({
baseURL: 'http://127.0.0.1:5000',
timeout: 5000
})
// 响应拦截器
instance.interceptors.response.use(response => {
console.log('成功拦截到响应');
console.log(response) //拦截成功后可以在此对response响应执行操作
return response.data //最后需要把拦截结果释放
}, err => {
console.log('拦截响应失败');
return err
})
// 发送网络请求
return instance(config)
}
效果展示:
后记
要在项目实战中多运用练习以加深印象。