# 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'
// 獲取所有資源
this.$axios.get('/users')
.then(response => {
console.log(response.data)
})
.catch(error => {
console.error(error)
})
// 帶參數GET請求
this.$axios.get('/users', {
params: {
ID: 12345
}
})
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')
// 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
})
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'
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編輯器中查看完整文檔并進行調整。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。