中古時代(若干年前)使用angular的時候,總結過《from屬性EncType提交數據的格式詳解—在angular中的應用》html
在遠古ie興盛的時代,基本是fromData提交數據,ajax+jquery推進了時代的變革,當數據提交也大抵如此,直到angularJS到來,先後端才通用json形式,轉眼從react跳轉到vue(感受被Vue強暴),閒話打住前端
理論上,一套api接口,通常統一json格式,要麼統一fromData,可是,就是有不按套路出牌(後端屌啊),三個都有vue
application/x-www-form-urlencodednode
multipart/form-datareact
application/jsonjquery
同時,接口返回數據,理論上應該統一規劃,好比消息屬性(toast統一處理),數據分層,可是,淚崩ios
axios封裝是必須,可是,前端時候也得考慮下規範(架構設計)方面的問題——小白秉性暴露無遺
web
看了axios源碼ajax
+axios
vuex
index.js
index.d.ts
+lib
axios.js
+core
Axios.js
axios自己就會檢測數據,匹配不一樣Content-Type
transformRequest: [function transformRequest(data, headers) {
normalizeHeaderName(headers, 'Content-Type');
if (utils.isFormData(data) ||
utils.isArrayBuffer(data) ||
utils.isBuffer(data) ||
utils.isStream(data) ||
utils.isFile(data) ||
utils.isBlob(data)
) {
return data;
}
if (utils.isArrayBufferView(data)) {
return data.buffer;
}
if (utils.isURLSearchParams(data)) {
setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
return data.toString();
}
if (utils.isObject(data)) {
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
return JSON.stringify(data);
}
return data;
}],複製代碼
可是,實際提交都是 Object類型,因而就得轉
第一種處理模式,就是prototype大法,
axios.postForm = function (url, data, config = null) {
return new Promise(function (resolve, reject) {
config = {
method: 'post',
url: url,
data: () => {
let fromData = new FormData();
for (let i in data) {
fromData.append(i,data[i])
}
return fromData;
}
};
axios.request(config).then((response) => {
resolve(response)
}, err => {
reject(err);
})
})
};複製代碼
第二種,從新構造一個新的函數,call回調,或者
class http {
constructor(config) {
if (config) {
return new Promise((resolve, reject) => {
axios(config)
.then(function (response) {
});
});
}
}
static get(url, parma) {}
static post(url, param) {}
}複製代碼
發如今var axios= Create an instance of Axios,axios get post request 都是集中處理
Axios.prototype.request
// Provide aliases for supported request methods
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
/*eslint func-names:0*/
Axios.prototype[method] = function(url, config) {
return this.request(utils.merge(config || {}, {
method: method,
url: url
}));
};
});
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
/*eslint func-names:0*/
Axios.prototype[method] = function(url, data, config) {
return this.request(utils.merge(config || {}, {
method: method,
url: url,
data: data
}));
};
});複製代碼
因而決定,經過增長一個屬性聲明,如:commitType:'form'
因而,就會有以下代碼
import axios from 'axios';
import queryString from 'queryString';//nodeJs內置,無需npm i
axios.interceptors.request.use(function (config) {
//TODO 請求攔截
/*store.commit('updateLoadingStatus', {isLoading: true});*/
if (config.commitType) {
if (config.commitType === 'form') {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
config.transformRequest = [function (data) {
return queryString.stringify(data);//利用對應方法轉換格式
}]
} else if (config.commitType === 'url') {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
config.transformRequest = [function (data) {
return decodeURIComponent(data);
}];
}
}
console.log(config);
return config;
}, function (error) {
//請求錯誤時作些事
return Promise.reject(error);
});
//響應攔截器即異常處理
axios.interceptors.response.use(response => {
//TODO 統一處理邏輯
//store.commit('updateLoadingStatus', {isLoading: false});
if (response.data) {
return response.data;
}
return response
}, err => {
if (err && err.response) {
//http狀態碼處理
switch (err.response.status) {
case 400:
err.msg = '錯誤請求';
break;
case 401:
err.msg = '未受權,請從新登陸';
break;
case 403:
err.msg = '拒絕訪問';
break;
case 404:
err.msg = '請求錯誤,未找到該資源';
break;
case 405:
err.msg = '請求方法未容許';
break;
case 408:
err.msg = '請求超時';
break;
case 500:
err.msg = '服務器端出錯';
break;
case 501:
err.msg = '網絡未實現';
break;
case 502:
err.msg = '網絡錯誤';
break;
case 503:
err.msg = '服務不可用';
break;
case 504:
err.msg = '網絡超時';
break;
case 505:
err.msg = 'http版本不支持該請求';
break;
default:
err.msg = `鏈接錯誤${err.response.status}`
}
} else {
err.msg = '鏈接到服務器失敗';
}
return Promise.resolve(err.response)
});
//超時時間
axios.defaults.timeout = 5000;
export default axios;複製代碼
拓展文章:
Vue基於vuex、axios攔截器實現loading效果及axios的安裝配置
原文連接:www.zhoulujun.cn/html/webfro…(不定時更新)
文有不妥之處,請留言告知,謝謝!