基礎(chǔ)入門文檔建議直接查看Axios中文文檔暮屡,這樣能少走很多彎路
Axios中文文檔
封裝請求
在請求或響應(yīng)被 then 或 catch 處理前攔截它們
import axios from 'axios';
// axios 配置
var instance = axios.create({
headers:{
'Content-Type': 'application/json',
},
timeout: 30000,
baseURL: '', //接口請求地址
})
//攔截重復(fù)請求
let pending = []; //聲明一個數(shù)組用于存儲每個ajax請求的取消函數(shù)和ajax標(biāo)識
let cancelToken = axios.CancelToken;
let removeRepeatUrl = (config) => {
let comValue = config.method == 'get' ? qs.stringify(config.params) : qs.stringify(config.data);
for(let p in pending){
if(pending[p].u === config.url + '&' + config.method + '&' + comValue) { //當(dāng)前請求在數(shù)組中存在時執(zhí)行函數(shù)體
pending[p].f(); //執(zhí)行取消操作
pending.splice(p, 1); //把這條記錄從數(shù)組中移除
}
}
}
let saveRepeatUrl = (config) =>{
let comValue = config.method == 'get' ? qs.stringify(config.params) : qs.stringify(config.data);
console.log(comValue)
config.cancelToken = new cancelToken((c)=>{
pending.push({ u: config.url + '&' + config.method + '&' + comValue, f: c }); // 自定義唯一標(biāo)識
});
} }
}
// 添加請求攔截器
instance.interceptors.request.use(config => {
// 在發(fā)送請求之前做些什么筒主,比如傳token
removeRepeatUrl(config); //在一個ajax發(fā)送前執(zhí)行一下取消操作
saveRepeatUrl(config); //保存請求地址
return config
}, error => {
// 對請求錯誤做些什么
console.log(error) // for debug
return Promise.reject(error);
})
// 添加響應(yīng)攔截器
instance.interceptors.response.use(response => {
removeRepeatUrl(response.config); //執(zhí)行取消操作,把已經(jīng)完成的請求從pending中移除
// 對響應(yīng)數(shù)據(jù)做點什么
const res = response.data;
//對錯誤代碼做處理
return response;
}, error => {
// 對響應(yīng)錯誤做點什么
console.log('err' + error)// for debug
return Promise.reject(error);
});
export default instance;
/**
* post 請求方法
* @param url
* @param data
* @returns {Promise}
*/
export function post(url, data = {}) {
return new Promise((resolve, reject) => {
instance.post(url, data).then(response => {
//對接口錯誤碼做處理
resolve(response.data);
}, err => {
reject(err);
})
})
}
/**
* get 請求方法
* @param url
* @param data
* @returns {Promise}
*/
export function get(url, data = {}) {
return new Promise((resolve, reject) => {
instance.get(url, {
params: data
})
.then(response => {
resolve(response);
})
.catch(err => {
reject(err)
})
})
}
/**
* 封裝所有請求
* @param methed
* @param url
* @param data
* @param headers
* @returns {Promise}
*/
export function request(methed,url, data = {},headers) {
return new Promise((resolve, reject) => {
instance({
method: methed || 'post',
url:url,
params: methed === 'get' ? data :'',
data: methed !== 'get' ? data :'',
headers: headers || {'Content-Type':'application/json'},
})
.then(response => {
//對接口錯誤碼做處理
resolve(response.data);
})
.catch(err => {
reject(err)
})
})
}
調(diào)用方式
在 main.js文件中引用
import {post} from './utils/http'
Vue.prototype.$post = post;
最好將項目所有接口請求放在一個文件中,方便管理
新建文件api.js
import {request} from './axios.js'
//用戶登錄接口
export function userLogin(data){
return request('post','接口地址',data);
}
在其他頁面引用
import {userLogin} from './api.js'
userLogin({}).then(res=>{
});
axios跨域
方法一
在config的index.js文件中的dev屬性中添加一個屬性proxyTable:
proxyTable{
'/api':{
target:"URL",
changeOrigin:true,
pathRewrite:{
'^/api':""
}
}
}
然后在axios里面訪問 /api/xxx 就可以成功訪問了這種方式只能本地測試環(huán)境運行碟嘴,對正式環(huán)境無效(需要配置環(huán)境生效)
方法二:CORS(跨域資源共享)方案解決的跨域問題
跨域資源共享 CORS 詳解
攔截重復(fù)請求
請看上面封裝的請求代碼(掩耳盜鈴,只是攔截了服務(wù)端的響應(yīng),但是還是發(fā)了請求X远谩!7娇狻=嵝颉)
碰到的問題:
請求并沒有真正取消,數(shù)據(jù)還是給發(fā)送到服務(wù)器了纵潦,所以取消請求不是真的取消請求徐鹤?
正常情況下客戶端發(fā)送的請求服務(wù)器是會接收到然后做處理的。而所謂的abort邀层,是指不接收請求的響應(yīng)數(shù)據(jù)而不是攔截返敬。因此某種意義上對于get類的請求
來說是有效的,但是對post類請求不行被济。
http請求是基于tcp的救赐,abort取消的是http層面的請求涧团,如果abort的時候只磷,請求已經(jīng)到達(dá)tcp層面了最終是還會到達(dá)服務(wù)器端的经磅,只是不會再接收服務(wù)端的
響應(yīng)了