請求封裝
// ajax.js
import axios from 'axios';
import qs from 'qs'; //參數(shù)編譯
let pending = []; //聲明一個數(shù)組用于存儲每個ajax請求的取消函數(shù)和ajax標(biāo)識
let cancelToken = axios.CancelToken; //引入取消請求方法
//請求完成后取消該請求,從隊列刪除
let removePending = (ever) => {
for(let p in pending){
if(pending[p].u === ever.baseURL) { //當(dāng)前請求在隊列中存在時
pending[p].f(); //執(zhí)行取消操作
pending.splice(p, 1); //把這條記錄從隊列中移除
}
}
}
let baseURL
//項目需要,如果是開發(fā)環(huán)境走本地ip跨域訪問(前提是項目有多環(huán)境配置文件,配置有代理方法)
if (process.env.REACT_APP_ENV === 'development') {
baseURL = '/api'
} else {
//非開發(fā)環(huán)境下獲取配置文件的baseurl
baseURL = process.env.REACT_APP_BASE_URL
}
//請求封裝 method請求方法,全大寫 params參數(shù) url路徑
export const http = (method, params, url, preventRepeat=true,uploadFile=false) => {
return new Promise((resolve, reject) => {
const instance = axios.create({
baseURL: baseURL + url,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
//可添加其他公用參數(shù),比如token等
},
//設(shè)置超時
timeout: 50 * 1000
});
//默認(rèn)阻止重復(fù)請求
if (preventRepeat) {
// request攔截器
instance.interceptors.request.use(
config => {
removePending(config);//防止雙擊多次觸發(fā)請求
config.cancelToken = new cancelToken((c)=>{
pending.push({ u: config.baseURL, f: c });
});
return config;
},
err => {
return Promise.reject(err);
}
);
//response攔截器
instance.interceptors.response.use(
response => {
removePending(response.config);
return response;
},
error => {
return Promise.reject(error)
}
);
} else {
// 攔截器
instance.interceptors.request.use(
config => {
return config;
},
err => {
return Promise.reject(err);
}
);
instance.interceptors.response.use(
response => {
return response;
},
error => {
return Promise.reject(error)
}
);
}
// 請求(uploadFile為true表示上傳文件binary類型,則參數(shù)不需要編譯)
instance(
Object.assign(
{},
{method},
(method === 'POST' || method === 'PUT') ? {data: !uploadFile?qs.stringify(params):params} : {params}
)
).then(response => {
// success
if (response.data.code === 200) {
resolve(response.data);
} else {
resolve(false)
}
})
.catch(error => {
resolve(false)
});
});
}
使用
1.個人習(xí)慣,把所有api寫在一個文件里,默認(rèn)跟ajax.js同級目錄
//api.js
import {http} from './ajax.js'
//示例,默認(rèn)參數(shù)為空,特殊情況有些接口需要循環(huán)請求的,可以設(shè)置參數(shù)preventRepeat為false
//post
export const login = (params={}) => http('POST', params, '/login')
//get
export const getList = (params={}) => http('GET', params, '/list')
export const getDetail = (id,params={}) => http('GET', params, `/detail/${id}`)
2.在需要調(diào)用請求的頁面發(fā)起請求
import {login, getList, getDetail} from 'api.js' //根據(jù)自己項目文件的路徑來寫
//請求
login({name:'張三',password:'123456'})
getList() //沒有參數(shù)的情況
getDetail(1)
//異步處理等待請求完成獲取數(shù)據(jù)
async function getData () {
const data = await getDetail(1)
console.log(data)
}
getData()