再谈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中axios的使用技巧配置项详解

Vue基于vuex、axios拦截器实现loading效果及axios的安装配置

原文链接: www.zhoulujun.cn/html/webfro… (不定时更新)

文有不妥之处,请留言告知,谢谢!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

迎接互联网的明天

迎接互联网的明天

邹静 / 电子工业 / 2011-6 / 55.00元

《迎接互联网的明天-玩转3D Web(附盘)》,全书共5章,第1章主要阐述了国内外空前繁荣的3D互联网技术领域,以及这些领域透射出来的潜在商机;第2章主要用当下比较流行的Flash编程语言ActionScript 3,来向大家介绍面向对象编程语言的思想概念,以及一些3D渲染技术的入门知识;第3章注重建模知识的运用,主要运用WireFusion和3ds Max来制作3D网页;第4章主要介绍3D游戏编......一起来看看 《迎接互联网的明天》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试