再谈from属性EncType与axios分装—axios拦截器实现-源码浅析
栏目: JavaScript · 发布时间: 5年前
内容简介:中古时代(若干年前)使用angular的时候,总结过《在远古ie兴盛的时代,基本是fromData提交数据,ajax+jquery推动了时代的变革,当数据提交也大抵如此,直到angularJS到来,前后端才通用json形式,转眼从react跳转到vue(感觉被Vue强暴),闲话打住理论上,一套api接口,一般统一json格式,要么统一fromData,但是,就是有不按套路出牌(后端屌啊),三个都有
中古时代(若干年前)使用angular的时候,总结过《 from属性EncType提交数据的格式详解—在angular中的应用 》
在远古ie兴盛的时代,基本是fromData提交数据,ajax+jquery推动了时代的变革,当数据提交也大抵如此,直到angularJS到来,前后端才通用json形式,转眼从react跳转到vue(感觉被Vue强暴),闲话打住
理论上,一套api接口,一般统一json格式,要么统一fromData,但是,就是有不按套路出牌(后端屌啊),三个都有
application/x-www-form-urlencoded
multipart/form-data
application/json
同时,接口返回数据,理论上应该统一规划,比如消息属性(toast统一处理),数据分层,但是,泪崩
axios封装是必须,但是,前端时候也得考虑下规范(架构设计)方面的问题——小白秉性暴露无遗
看了axios源码
+axios
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… (不定时更新)
文有不妥之处,请留言告知,谢谢!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。