Vue怎么用Axios异步请求API

发布时间:2022-05-05 17:20:26 作者:iii
来源:亿速云 阅读:244
# Vue怎么用Axios异步请求API

## 前言

在现代Web开发中,前后端分离已成为主流架构模式。Vue.js作为一款渐进式JavaScript框架,通常需要与后端API进行数据交互。Axios是一个基于Promise的HTTP客户端,可以很好地满足这一需求。本文将详细介绍如何在Vue项目中使用Axios进行异步API请求。

## 目录

1. [Axios简介](#axios简介)
2. [安装与配置](#安装与配置)
3. [基本请求方法](#基本请求方法)
4. [请求与响应拦截](#请求与响应拦截)
5. [错误处理](#错误处理)
6. [高级配置](#高级配置)
7. [与Vuex结合使用](#与vuex结合使用)
8. [性能优化](#性能优化)
9. [安全实践](#安全实践)
10. [常见问题](#常见问题)

## Axios简介

Axios是一个基于Promise的HTTP客户端,适用于浏览器和Node.js环境。它具有以下特点:

- 从浏览器创建XMLHttpRequests
- 从Node.js创建http请求
- 支持Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF

## 安装与配置

### 安装Axios

在Vue项目中安装Axios:

```bash
npm install axios
# 或
yarn add axios

全局配置

在main.js中全局引入:

import axios from 'axios'

// 设置基础URL
axios.defaults.baseURL = 'https://api.example.com'

// 设置超时时间
axios.defaults.timeout = 10000

// 设置请求头
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

Vue.prototype.$axios = axios

按需引入

也可以在组件中按需引入:

import axios from 'axios'

基本请求方法

GET请求

// 获取所有资源
this.$axios.get('/users')
  .then(response => {
    console.log(response.data)
  })
  .catch(error => {
    console.error(error)
  })

// 带参数GET请求
this.$axios.get('/users', {
  params: {
    ID: 12345
  }
})

POST请求

this.$axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(response => {
  console.log(response)
})
.catch(error => {
  console.log(error)
})

并发请求

function getUserAccount() {
  return axios.get('/user/12345')
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions')
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread((acct, perms) => {
    // 两个请求都完成后执行
  }))

请求与响应拦截

请求拦截器

axios.interceptors.request.use(
  config => {
    // 在发送请求前做些什么
    const token = localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  error => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

响应拦截器

axios.interceptors.response.use(
  response => {
    // 对响应数据做点什么
    return response.data
  },
  error => {
    // 对响应错误做点什么
    if (error.response) {
      switch (error.response.status) {
        case 401:
          router.replace('/login')
          break
        case 404:
          router.replace('/404')
          break
      }
    }
    return Promise.reject(error)
  }
)

错误处理

基本错误处理

axios.get('/user/12345')
  .catch(error => {
    if (error.response) {
      // 请求已发出,服务器返回状态码不在2xx范围内
      console.log(error.response.data)
      console.log(error.response.status)
      console.log(error.response.headers)
    } else if (error.request) {
      // 请求已发出但没有收到响应
      console.log(error.request)
    } else {
      // 发送请求时发生错误
      console.log('Error', error.message)
    }
    console.log(error.config)
  })

自定义错误处理

const handleError = error => {
  const errorMap = {
    400: '请求参数错误',
    401: '未授权,请登录',
    403: '拒绝访问',
    404: '请求地址不存在',
    500: '服务器内部错误',
    502: '网关错误',
    503: '服务不可用',
    504: '网关超时'
  }
  
  const status = error.response?.status
  const message = errorMap[status] || '未知错误'
  
  Message.error(message)
  return Promise.reject(error)
}

axios.interceptors.response.use(null, handleError)

高级配置

取消请求

const CancelToken = axios.CancelToken
let cancel

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    cancel = c
  })
})

// 取消请求
cancel()

上传进度

axios.post('/upload', formData, {
  onUploadProgress: progressEvent => {
    const percentCompleted = Math.round(
      (progressEvent.loaded * 100) / progressEvent.total
    )
    console.log(percentCompleted)
  }
})

自定义实例

const instance = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
})

// 使用实例
instance.get('/users')

与Vuex结合使用

在actions中使用

// store.js
actions: {
  fetchUser({ commit }, userId) {
    return new Promise((resolve, reject) => {
      axios.get(`/users/${userId}`)
        .then(response => {
          commit('SET_USER', response.data)
          resolve(response)
        })
        .catch(error => {
          reject(error)
        })
    })
  }
}

组件中调用

methods: {
  getUser() {
    this.$store.dispatch('fetchUser', this.userId)
      .then(() => {
        // 成功处理
      })
      .catch(error => {
        // 错误处理
      })
  }
}

性能优化

请求节流

import _ from 'lodash'

methods: {
  search: _.debounce(function() {
    axios.get('/search', { params: { q: this.query } })
      .then(response => {
        this.results = response.data
      })
  }, 500)
}

缓存响应

const cache = new Map()

axios.interceptors.request.use(config => {
  if (config.method === 'get' && cache.has(config.url)) {
    return Promise.resolve(cache.get(config.url))
  }
  return config
})

axios.interceptors.response.use(response => {
  if (response.config.method === 'get') {
    cache.set(response.config.url, response)
  }
  return response
})

安全实践

CSRF防护

axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'

JWT认证

axios.interceptors.request.use(config => {
  const token = localStorage.getItem('token')
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
})

axios.interceptors.response.use(response => {
  return response
}, error => {
  if (error.response.status === 401) {
    // 刷新token或跳转登录
  }
  return Promise.reject(error)
})

常见问题

跨域问题

配置代理:

// vue.config.js
module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
}

处理二进制数据

axios.get('/download', {
  responseType: 'blob'
})
.then(response => {
  const url = window.URL.createObjectURL(new Blob([response.data]))
  const link = document.createElement('a')
  link.href = url
  link.setAttribute('download', 'file.pdf')
  document.body.appendChild(link)
  link.click()
})

请求超时重试

axios.interceptors.response.use(null, error => {
  const config = error.config
  if (!config || !config.retry) return Promise.reject(error)
  
  config.__retryCount = config.__retryCount || 0
  
  if (config.__retryCount >= config.retry) {
    return Promise.reject(error)
  }
  
  config.__retryCount += 1
  
  const backoff = new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, config.retryDelay || 1000)
  })
  
  return backoff.then(() => axios(config))
})

结语

本文详细介绍了在Vue项目中使用Axios进行API请求的各种方法和最佳实践。通过合理配置Axios,可以大大提高开发效率和应用程序的健壮性。建议根据项目实际需求选择合适的配置方案,并注意安全性问题。

希望本文能帮助您更好地在Vue项目中使用Axios进行API请求。Happy coding! “`

注意:实际字数可能因格式和具体内容略有差异。如需精确控制字数,建议在Markdown编辑器中查看完整文档并进行调整。

推荐阅读:
  1. axios异步请求数据的使用案例
  2. vue.js中axios怎么用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue axios api

上一篇:Vue怎么制作Todo List网页

下一篇:vue如何生成文件本地打开查看效果

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》