axios插件介绍及使用

js yekong

Axios是一个基于Promise的现代HTTP客户端,用于在浏览器和Node.js中发送HTTP请求。它支持多种功能,例如拦截请求和响应、取消请求、自动转换JSON数据等。Axios插件是为了扩展Axios的功能而创建的,你可以使用插件来添加全局的请求拦截、响应拦截、错误处理等功能,以及在请求或响应之前对数据进行预处理。

安装依赖

npm install axios

get请求实例

无参数请求实例

getData() {
  const apiUrl = 'https://api.wanjunshijie.com/data';

  axios.get(apiUrl)
    .then(response => {
      // 请求成功时,将响应数据存储到 dataList 中
      this.dataList = response.data;
    })
    .catch(error => {
      // 处理错误
      console.error('Error:', error);
    });
}

多参数请求实例

getData() {
  const apiUrl = 'https://api.wanjunshijie.com/data';
  const category = 'example_category';
  const startDate = '2023-01-01';
  const endDate = '2023-12-31';

  axios.get(apiUrl, {
    params: {
      category: category,
      startDate: startDate,
      endDate: endDate
    }
  })
    .then(response => {
      // 请求成功时,将响应数据存储到 dataList 中
      this.dataList = response.data;
    })
    .catch(error => {
      // 处理错误
      console.error('Error:', error);
    });
}

post请求实例

submitForm() {
    const apiUrl = 'https://api.wanjunshijie.com/register';
    const formData = {
        username: this.username,
        email: this.email,
        password: this.password
    };
    
    axios.post(apiUrl, formData)
    .then(response => {
      // 处理成功响应,例如显示成功提示或跳转到其他页面
      console.log('Registration successful:', response.data);
    })
    .catch(error => {
      // 处理错误,例如显示错误提示
      console.error('Registration failed:', error);
    });
}

下载文件

使用 Axios 下载流文件时,需要设置 responseType'blob'(二进制数据),这样 Axios 将以二进制格式处理响应数据。然后,你可以将下载的文件保存到本地或执行其他处理。

以下是一个在 Vue.js 中使用 Axios 下载流文件的示例:

<template>
  <div>
    <button @click="downloadFile">Download File</button>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  methods: {
    downloadFile() {
      const downloadUrl = 'https://example.com/files/sample.pdf'; // 替换为你要下载的文件 URL
      const filename = 'sample.pdf'; // 下载后保存的文件名

      axios.get(downloadUrl, {
        responseType: 'blob' // 设置响应数据类型为二进制数据
      })
      .then(response => {
        // 创建一个 blob 对象
        const blob = new Blob([response.data], { type: response.headers['content-type'] });

        // 创建一个隐藏的链接并设置下载属性
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', filename);

        // 触发链接点击事件
        document.body.appendChild(link);
        link.click();

        // 清理链接和释放 blob 对象
        link.remove();
        window.URL.revokeObjectURL(url);
      })
      .catch(error => {
        console.error('Error:', error);
      });
    }
  }
};
</script>

在这个示例中,我们定义了一个按钮,并在按钮点击时触发 downloadFile 方法。在 downloadFile 方法中,我们使用 axios.get() 方法发送 GET 请求,并设置 responseType'blob'

当请求成功后,我们获取到响应的二进制数据,并根据响应头中的 'content-type' 创建一个 Blob 对象。然后,我们创建一个隐藏的链接,将 Blob 对象的 URL 设置为链接的 href 属性,并设置链接的 download 属性为要保存的文件名。最后,我们触发链接的点击事件来下载文件,并在下载完成后清理链接和释放 Blob 对象。

请注意,你需要将 downloadUrl 替换为你要下载的实际文件的 URL,并根据需要修改 filename 来设置保存的文件名。

这个示例演示了如何使用 Axios 下载流文件,并将其保存到本地,你可以根据项目的需求进行调整和优化。

代码封装包含token刷新 401处理

ipConfig.js

var url1 = '' // 正式接口
var url2 = 'http://192.168.235.157' // 调试接口
var ip = process.env.NODE_ENV === 'production' ? url2 : url2

export const devIp = ip
export const testIp = ip
export const timing = 10000

request.js

import axios from 'axios'
// import {Message} from 'element-ui'
import {devIp} from '@/api/ipConfig'
// 刷新token的一个开关,防止重复请求
let isRefreshing = true;

const service = axios.create({
    baseURL: devIp + '', // 测试IP
    timeout: 100000, // request timeout
})

// request interceptor
service.interceptors.request.use(config => {
    let token = localStorage.getItem('access_token')
    if (token) {
        config.headers['Authorization'] = 'Basic c2FiZXI6c2FiZXJfc2VjcmV0' // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
        config.headers['Blade-Auth'] = token // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
    }
    return config
}, error => {
    Promise.reject(error)
})

// respone interceptor
service.interceptors.response.use(
    // response => response,
    response => {
        const res = response.data
        return res;
    },
    error => {
        if (error.response.data.code == 401) {
            if (isRefreshing) {
                isRefreshing = false;
                return refreshToken().then((res) => {
                    const data = res.data;
                    if (data.access_token) {
                        localStorage.setItem('access_token', data.access_token)
                        // 已经刷新了token,将所有队列中的请求进行重试
                        window.location.reload();
                    } else {
                        return false;
                    }
                }).catch(() => {
                    return false;
                }).finally(() => {
                    isRefreshing = true
                })
            }
        }
        return Promise.reject(error)
    })

// 刷新token请求
function refreshToken() {
    return axios.post(`${devIp}/api/blade-auth/oauth/token?tenantId=000000&username=DP001223232&password=efc3d451b28e586&grant_type=password&scope=all&type=account`, null, {
        headers: {
            'Tenant-Id': '000000',
            'Authorization': 'Basic c2FiZXI6c2FiZXJfc2VjcmV0'
        }
    });
}

export default service

api.js

import request from '../request'
import qs from 'qs'

// 部门数量
export function dockerconfig(data) {
    return request({
        url: '/api/blade-government/dockerconfig/page',
        method: 'get',
        data
    })
}

// 部门数量
export function data_column_list(data) {
    return request({
        url: '/api/blade-xmjc/data/data_column_list',
        method: 'post',
        data
    })
}

请求数据

import {data_column_list,} from "@/api/api/user.js";

getData() {
  var that = this;
  data_column_list({current: 1, size: 1000, tableId: this.id}).then(res => {
    that.num = res.data.total
    that.list = res.data.records
  }).catch(err => {
  })
},

实现文件上传

使用 Axios 实现文件上传可以通过发送 POST 请求,并使用 FormData 对象来传递文件数据。以下是实现文件上传的示例代码:

<template>
  <div>
    <input type="file" ref="fileInput" @change="handleFileChange">
    <button @click="uploadFile">Upload</button>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  methods: {
    handleFileChange(event) {
      // 获取选择的文件
      this.selectedFile = event.target.files[0];
    },
    uploadFile() {
      if (!this.selectedFile) {
        alert('Please select a file to upload.');
        return;
      }

      // 创建 FormData 对象,用于包装文件数据
      const formData = new FormData();
      formData.append('file', this.selectedFile);

      // 使用 Axios 发送 POST 请求上传文件
      axios.post('https://api.example.com/upload', formData, {
        headers: {
          'Content-Type': 'multipart/form-data' // 设置请求头为 multipart/form-data
        }
      })
        .then(response => {
          // 处理上传成功的响应
          alert('File uploaded successfully!');
          console.log('Response:', response.data);
        })
        .catch(error => {
          // 处理上传失败的错误
          alert('File upload failed.');
          console.error('Error:', error);
        });
    }
  }
};
</script>

在这个示例中,我们创建了一个包含文件上传功能的 Vue 组件。用户可以通过选择文件按钮选择要上传的文件,并通过 handleFileChange 方法来获取选择的文件。

在上传文件时,我们使用 FormData 对象来包装文件数据,并通过 append 方法将选中的文件添加到 formData 中,'file' 是你要设置的文件参数名称,可以根据后端的要求进行调整。

然后,我们使用 Axios 的 post 方法来发送 POST 请求,并将 formData 作为请求体传递给服务器。同时,我们设置了请求头的 'Content-Type''multipart/form-data',以告诉服务器我们发送的是文件数据。

上传成功后,我们可以在 then 方法中处理成功的响应,并在 catch 方法中处理上传失败的错误。

请注意,这里的上传地址 'https://api.example.com/upload' 应该替换为实际的上传 API 地址。另外,确保服务器能够正确处理文件上传,并根据服务器的要求设置相应的请求头和参数名。

以上示例演示了如何使用 Axios 实现文件上传,你可以根据你的项目需求进行调整和优化。

jsonbig长数值精度丢失

安装依赖

npm i JSONbig --save

在axios.create添加

const service = axios.create({
    baseURL: devIp + '', // 测试IP
    timeout: 100000, // request timeout,
    transformResponse: [function (data) {
        try {
            // 如果转换成功则返回转换的数据结果
            return JSONbig.parse(data)
        } catch (err) {
            // 如果转换失败,则包装为统一数据格式并返回
            return {
                data
            }
        }
    }]
});
import axios from 'axios';
import {ElMessage} from 'element-plus'
import {devIp} from '@/api/ipConfig';
import router from "@/router";
import JSONbig from 'json-bigint'

const service = axios.create({
    baseURL: devIp + '', // 测试IP
    timeout: 100000, // request timeout,
    transformResponse: [function (data) {
        try {
            // 如果转换成功则返回转换的数据结果
            return JSONbig.parse(data)
        } catch (err) {
            // 如果转换失败,则包装为统一数据格式并返回
            return {
                data
            }
        }
    }]
});

// request interceptor
service.interceptors.request.use(config => {
    let uid = sessionStorage.getItem('token');
    if (uid) {
        config.headers['token'] = uid; // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
    }
    return config;
}, error => {
    Promise.reject(error);
});

// respone interceptor
service.interceptors.response.use(
    // response => response,
    response => {
        const res = response.data;
        // return res;
        if (res.code == '200') {
            return res;
        } else if (res.code == '401') {
            sessionStorage.removeItem('token')
            router.push({path: '/login'});
            ElMessage({
                message: res.msg,
                type: 'error',
                duration: 2 * 1000
            });
        } else {
            ElMessage({
                message: res.msg,
                type: 'error',
                duration: 5 * 1000
            });
            return res;
        }
    },
    error => {
        console.log('err' + error);// for debug
        ElMessage({
            message: error.message,
            type: 'error',
            duration: 3000
        });
        return Promise.reject(error);
    });

export default service;

vue2中的中断请求

vue项目开发中,会遇到切换页面时,上一个页面的接口还在请求,当只有一两个页面的时候,无所谓,但是当页面有几十个接口的话,就有必要切换页面是,结束上一页未完成的无效请求,以节省接口资源。
切换页面时,由于上一页面请求执行时间长,切换到该页面时,还未执行完,这时那个请求仍会继续执行直到请求结束,此时将会影响页面性能,并且可能对现在页面的数据显示造成一定影响,所以我们应该,切换页面前中断前面所有请求。
调整后页面切换接口请求效果

vue 切换页面中断axios请求避免阻塞

文件调整

main.js

//  cancelToken中的cancel函数
Vue.$httpRequestList=[];

Axios配置文件

Axios 提供了一个 CancelToken的函数,这是一个构造函数,该函数的作用就是用来取消接口请求的。

import Vue from 'vue'
import router from '../router'
// create an axios instance
const CancelToken = axios.CancelToken
// 在请求拦截器里面 统一添加 取消请求
request.interceptors.request.use(config => {
  // 强行中断请求要用到的,记录请求信息
  config['cancelToken'] = new CancelToken(function executor(cancel) {
      Vue.$httpRequestList.push(cancel) //存储cancle
  })
  config.headers = { ...config.headers, ...config.config.headers }
  ... ... 
  return config;
});

// response拦截器
// 在响应拦截器里面 统一添加 处理取消请求
request.interceptors.response.use(response => {
  ... ...
}, error => {
  if(error.message === 'interrupt') {
    console.log('请求中断');
    return new Promise(() => {});
  }
  // Vue.$httpRequestList = [];
  return Promise.reject(error)
});

路由文件

在路由守卫中,写一个执行cancel方法的clearHttpRequestingList方法,在每次跳转之前执行clearHttpRequestingList()函数

/**
* 在路由切换之前检测来中断上个页面的请求
*/
router.beforeEach((to, from, next) => { 
  clearHttpRequestingList();
  next();
});

// 清空cancelToken中的cancel函数
function clearHttpRequestingList() {
  // 路由切换检测是否强行中断, 强行中断时才向下执行
  if (Vue.$httpRequestList.length > 0) {
    Vue.$httpRequestList.forEach((item) => {
      // 给个标志,中断请求
      item('interrupt');
    })
    Vue.$httpRequestList = [];
  }
}

vuex 调整

export default createStore({
  state: {
    httpRequestList: [],
  },
  mutations: {
    addHttpRequestList(state, payload) {
      if (payload == 0) {
        //强行中断时才向下执行
        state.httpRequestList.forEach(item => {
          item("interrupt"); //给个标志,中断请求
        });
        state.httpRequestList = [];
      } else {
        state.httpRequestList.push(payload);
      }
    },
  },
  actions: {
    async removeHttpRequestList(ctx) {
      ctx.commit("addHttpRequestList", 0);
    },
  },
});
喜欢