axios(封裝使用、攔截特定請求、判斷所有請求加載完畢)
阿新 • • 發佈:2019-04-09
做出 page push cover arr 登錄 開發 自動識別 ram
博客地址:https://ainyi.com/71
- 基於 Promise 的 HTTP 請求客戶端,可同時在瀏覽器和 Node.js 中使用
- vue2.0之後,就不再對 vue-resource 更新,而是推薦使用 axios,本項目也是使用 axios
- 功能特性
- 在瀏覽器中發送 XMLHttpRequests 請求
- 在 node.js 中發送 http請求
- 支持 Promise API
- 攔截請求和響應
- 轉換請求和響應數據
- 取消請求
- 自動轉換 JSON 數據
- 客戶端支持保護安全免受 CSRF/XSRF(跨站請求偽造) 攻擊
封裝使用
建議拆分三個文件
- src
-> service
---->axios.js (axios 配置,攔截器、統一 url)
---->api
------->index.js(api 方法,裏面調用後端提供的接口,供接口方法調用)
axios.js 基本配置
'use strict'; import axios from 'axios'; // 自動識別接口使用開發環境地址(開發環境地址做了 proxyTable 代理,故設置為空)或線上地址 axios.defaults.baseURL = process.env.NODE_ENV === 'production' ? process.env.API_ROOT : ''; // 開發環境直接打包測試 // axios.defaults.baseURL = ''; axios.interceptors.request.use(config => { return config; }, error => { console.log(error); return Promise.reject(error); }); axios.interceptors.response.use(res => { const apiRes = res.data; return apiRes; }, async error => { console.dir(error); return Promise.reject(error); }); export default axios;
api/index.js 調用後端提供的接口
import Ax from '@/service/axios'; import qs from 'qs'; export default { fetchBlog (reqData) { return Ax.get('/krryblog/blog/getBlog', {params: reqData}); }, addBlog (reqData) { return Ax.post('/krryblog/blog/addBlog', qs.stringify(reqData)); }, updateBlog (reqData) { return Ax.post('/krryblog/blog/updateBlog', qs.stringify(reqData)); }, deleteBlogCover (id, reqData) { return Ax.post(`/krryblog/blog/deleteBlogCover/${id}`, qs.stringify(reqData)); }, };
index.js 接口方法(調用 api)
import Api from './api';
export async function getBlog(reqData) {
let res = await Api.fetchBlog(reqData);
return res;
},
export async function addBlog (reqData) {
let res = await Api.addBlog(reqData);
return res;
},
export async function updateBlog (reqData) {
let res = await Api.updateBlog(reqData);
return res;
},
export async function deleteBlogCover (id, reqData) {
let res = await Api.deleteBlogCover(id, reqData);
return res;
},
頁面調用
接下來就可以愉快地在頁面調用了
import { getBlog } from '@/service'
export default {
data() {
return {
tableData: [],
pageIndex: 1,
pageSize: 9
}
},
created() {
this.getList();
},
methods: {
async getList() {
let { result } = await getBlog({
pageIndex: this.pageIndex,
pageSize: this.pageSize
});
this.tableData = result.data;
},
}
axios 執行多個並發請求
async getList() {
let resArr = []
for (let val of this.arrId) {
// push 請求
resArr.push(queryPropertyValue({ id: val }))
}
this.tableData = []
Promise.all(resArr).then(res => {
for (let val of res) {
let vals = val.result.propertyValues
// 每個請求的結果 push 到 tableData
vals.forEach(item => this.tableData.push(item))
}
})
},
或者直接在 axios 寫 promise all
// 根據 id 獲取某一條商品數據
let getDetail = (id)=>{
return axios.get(`/detail?bid=${id}`);
}
// 檢測登錄的用戶是否將此商品加入購物車
let detectCar = (shopId,userId)=>{
return axios.get(`/detectCar?shopId=${shopId}&userId=${userId}`);
}
// 獲取一條商品數據、並且檢測是否加入購物車
let getDeAll = (shopId,userId)=>{
axios.all([
getDetail(shopId),
detectCar(shopId,userId)
]).then(axios.spread((resDetail, resCar)=>{
// 兩個請求現已完成
// 打印兩個請求的響應值
console.log(resDetail);
console.log(resCar);
}));
}
- 實例的方法
axios#request(config)
axios#get(url [,config])
axios#delete(url [,config])
axios#head(url [,config])
axios#post(url [,data [,config]])
axios#put(url [,data [,config]])
axios#patch(url [,data [,config]])
- 請求配置:只有url是必需的,如果未指定方法,請求將默認為GET
axios 攔截特定請求
業務上經常出現這個問題,需要攔截某些特定請求,在該特定請求,頁面采取或不采取什麽變化
研究 axios 的 request 統一攔截方法:axios.interceptors.request.use(function (config) {})
參數 config 如下:
可以發現 config.url 就是請求的接口的地址,那麽 “/” 最後的 getClassify 就是該請求的方法,就可以通過取出該字符串來判斷某些特定請求,從而做出怎樣的變化
axios.interceptors.request.use(config => {
// 判斷請求是否是 getClassify,如果是 getClassify,不加載 LoadingBar
let url = config.url;
if (url.split('/').pop() === 'getClassify') {
flag = false;
} else {
iView.LoadingBar.start();
flag = true;
}
return config;
}, error => {
console.log(error);
return Promise.reject(error);
});
如何判斷所有請求加載完畢
let reqNum = 0
axios.interceptors.request.use(function (config) {
// 在請求發出之前進行一些操作,每次發出請求就 reqNum++
reqNum++
_bus.$emit('showloading')
return config
}
axios.interceptors.response.use(response => {
// 接受請求後 reqNum--,判斷請求所有請求是否完成
reqNum--
if (reqNum <= 0) {
_bus.$emit('closeLoading')
} else {
_bus.$emit('showloading')
}
})
axios 的 post 請求 相關問題
- 如果遇到 post 請求跨域問題,在 webpack 配置文件可以設置 proxyTable 處理跨域問題
- 傳送門:https://ainyi.com/27
- post 請求攜帶參數,需要做一次序列化:qs.stringify(reqData)
saveNormalAds (reqData) {
return Ax.post('/index.php?krry', qs.stringify(reqData));
},
博客地址:https://ainyi.com/71
axios(封裝使用、攔截特定請求、判斷所有請求加載完畢)