中古時代(若干年前)使用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
+axiosvuex
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;
原文連接:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue/8137.html(不定時更新)
文有不妥之處,請留言告知,謝謝!
拓展文章: