Vue学习-axios

2022-02-17 15:50:28 浏览数 (1)

前言

本文将介绍axios的相关操作。

相关的后端服务器是用Flask搭建的,仅用于演示:

web.py

代码语言:javascript复制
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

代码语言:javascript复制
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:用于指定请求方式(getpost),不写该参数默认使用get方式
  • params:用于附带参数信息

值得注意的是axios已集成Promise,在发送请求后会自动执行resolve()函数,因此可以在后面直接链接then()函数,用于接收请求返回值。

web.py

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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()方法可以直接拆分返回结果列表,拿到具体的结果:

代码语言:javascript复制
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对象中添加诸如baseURLtimeout等的配置信息:

代码语言:javascript复制
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

代码语言:javascript复制
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()

代码语言:javascript复制
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的文件:

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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)
}

效果展示:


后记

要在项目实战中多运用练习以加深印象。

0 人点赞