# axios

官方传送门 (opens new window)

# 安装 引用 注册

npm install axios --save

// 全局注册 main.js
import axios from "axios"
// 把axios挂载到Vue.prototype上,供每个.vue组件的实例直接使用
Vue.prototype.$axios = axios
this.$axios
// $axios 这个是自己取的
1
2
3
4
5
6

在每个.vue组件中发起请求,直接调用this.$axios.xxx
但是,把axios挂载到Vue原型上,有个缺点,不利于API接口的复用

# 功能特点

  • 在浏览器中发送XMLHttpRequests请求
  • 在node.js中发送http请求
  • 支持Promise API
  • 拦截请求和响应
  • 转换请求和响应数据

# 响应结果的结构

响应结果的结构

  • config: 配置对象
  • data : 响应体 服务器返回的内容
  • header: 响应头部信息
  • request: Ajax
  • status: 响应值
  • statusText:响应状态

# 写法

# 1 基础,自己第一次用axios时的记录

// 类似这种 直接在写了 没有封装
axios({
  url:'http://bit.ly/2mTM3nY',
  method:'get',
  data:{},
  headers:{}
})
  .then((response) =>{
    console.log("返回的值:",response)
  });
1
2
3
4
5
6
7
8
9
10

# 2 axios并行发送请求

类似于Promise axios.all([axios(), axios()]).then((results) => {});

  • 返回的results会是数组类型:(顺序相互对应) axios并行发送

  • 单独将结果拿出来: axiosSpread方法

# 3 创建axios实例

const instance = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000
});

// 可以创建多个实例
instance({url:"/home/user"})
.then(res=>{console.log(res)})

instance({url:"/home/name"})
.then(res=>{console.log(res)})
1
2
3
4
5
6
7
8
9
10
11

# 模块封装(重要)

# 封装1

// xxxx_api.js

import Axios from "axios";

export function headerConfig_api(path, data) {
    let url = window.apiRoot.api53 + ':8227';
    url = url + path;
    let headers = {
        'Content-Type': 'application/json',
        'companyId': companyId
    };
    let method = "post";
    return Axios({
        url: url,
        method: method,
        headers: headers,
        data: data
    });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 文件 xxx.vue
  let path = '/report/getSimpleReport'
  let data = {
    "tableName": "header_config",
    "sort": "ASC",
    "sortColumn": "order_id",
    "query": {
      "report_name": "scclReportForm1"
    }
  }
  headerConfig_api(path, data)
    .then(response => {
      let result = response.data.data;
      console.log("获取表头", result);
    })
    .catch(err => {
      console.log(err);
    })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 封装2 用了拦截器

// utils/request.js 拦截器
import axios from 'axios' //引入axios
import { Toast } from "@nutui/nutui";
let baseURL = process.env.VUE_APP_COM;

const service = axios.create({
    // api 的 baseUrl 就是每个请求前面相同的地址,这个地方因为我配置了环境,所以直接取环境里的配置
    baseURL: baseURL,
    timeout: 300000 // 请求超时时间
});
// request拦截器
service.interceptors.request.use(
    config => {
        //这里是每个请求的设置,比如每个请求都携带一个token,或者当为post请求时,引入qs格式化参数。
        config.headers['content-type'] = "application/json";
        return config
    },
    error => {
        console.log('请求失败:' + error);
        Promise.reject(error)
    }
);
// response 拦截器
service.interceptors.response.use(
    response => {
        const res = response.data;
        //这个地方的code自己与后台约定(可以根据状态码,设置自己要提示的信息)
        // if (res._code !== '10000') {
        //     //在此可以加几种比较普遍的设置,然后可以把单独的返到页面中设置
        //     return Promise.reject(res)
        // } else {
        //     return response.data
        // }
        return response.data
    },
    error => {
        Toast.text("服务器错误,请联系管理员!",{id:"global_toast"});
        console.log('响应失败:' + error);
        return Promise.reject(error)
    }
);
export default service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// xxx_api.js
//引入配置好的axios
import request from '@/utils/request'
let VUE_BASE = process.env.VUE_APP_CDTJ_URL;

export const flawInfoByBarCode_api = (data) => {
    return request({
        url: VUE_BASE + "/getFlawInfoByBarCode",
        method: 'post',
        data,
    })
};
1
2
3
4
5
6
7
8
9
10
11
12
// xxx.vue文件
let data = {
     "companyId": this.companyId,
     "barCode": this.code,
   }
flawInfoByBarCode_api(data)
  .then(res=>{console.log(res)})
  .catch(err=>{console.log(err)})  

1
2
3
4
5
6
7
8
9

# 取消发送

问题: 数据渲染在一个dom上,点击按钮(快速切换),会导致前面没有完成的接口发送得到的数据 ,和现在接口发送得到的数据 堆叠 解决: 所以需要,将前面没有完成的接口 取消发送

# (一)封装好的API配置 步骤

# 步骤1: 配置封装好的API

//在common_api.js文件中
//配置 终止请求
export function aireport_common_api(path, companyId, that) {
    let url = 'http://120.55.124.53:9942'
    url = url + path;
    let method = "post";
    let headers = {
        'Content-Type': 'application/json',
        'companyId': companyId
    }
    return Axios({
        url: url,
        method: method,
        headers: headers,
        cancelToken: new axios.CancelToken(function executor(c) {
            that.source = c
        })
    })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 步骤2:定义一个方法

//在 引用 接口的文件 .vue中
  methods: {
    //取消未完成的请求
    cancelQuest() {
      if (typeof this.source === "function") {
        this.source("终止请求");
      }
    },
}
1
2
3
4
5
6
7
8
9

# 步骤3:在发送现在的接口请求之前,调用上面的方法,取消前面还在发送的请求

//在 引用 接口的文件 .vue中
   // 请求发送前调用
   this.cancelQuest();
   // 调用接口,注意,这里的this
    aireport_common_api(path, companyId, this).then((Response) => {
1
2
3
4
5

# (二)配置没有封装的API(没有使用过,官网是这么写的)

Axios 使用 cancel token 取消请求
Axios的 cancel token API 基于cancelable promises proposal,它还处于第一阶段.
可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/user/12345', {
 cancelToken: source.token
}).catch(function(thrown) {
 if (axios.isCancel(thrown)) {
  console.log('Request canceled', thrown.message);
 } else {
  // 处理错误
 }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

2.还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

var CancelToken = axios.CancelToken;
var cancel;

axios.get('/user/12345', {
 cancelToken: new CancelToken(function executor(c) {
  // executor 函数接收一个 cancel 函数作为参数
  cancel = c;
 })
});

// 取消请求
cancel();


1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 发送text格式

this.measurement 是变量

  let url = "http://36.26.85.213:8086/api/v2/query?org=th";
  let headers = {
    Authorization:
      "Token Z4s5lPSdXHs_zueTttAvcNQS9KyidZ-c4yOtiBaJltklkJWMk9EDla90idvh8kKkDp7eVIrRFoM5ByWB9AhFVA==",
    "Content-Type": "application/vnd.flux",
  };
  let data =
    'from(bucket: "tianheng")\n' +
    "|> range(start: -1h)\n" +
    // '|> filter(fn: (r) => r["_measurement"] == "sizing_10000012")\n' +
    '|> filter(fn: (r) => r["_measurement"] == ' +"\""+this.measurement+"\"" +
    ")\n" +
    '|> filter(fn: (r) => r["machine_id"] == "sj0103")\n' +
    '|> filter(fn: (r) => r["_field"] == "current_speed")\n' +
    "|> limit(n: 100)\n" +
    "|> timeShift(duration: 8h)\n";
  axios({
    url: url,
    method: "post",
    headers: headers,
    data: data,
  }).then((res) => {
    console.log(res);
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 拦截器(重要)还需要仔细看看

  1. 请求拦截
  • 请求成功
  • 请求失败

什么时候用请求拦截器:

  • 比如一些信息不符合服务器的要求
  • 比如每次发送网络请求时,都希望在界面中显示一个请求的图标
  • 比如 某些网络请求(登录(token),必须携带一些特殊的信息
  1. 响应拦截
  • 响应成功
  • 响应失败
Last Updated: 9/22/2022, 1:33:05 PM