再谈from属性EncType与axios分装—axios拦截器实现-源码浅析

栏目: JavaScript · 发布时间: 6年前

内容简介:中古时代(若干年前)使用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… (不定时更新)

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


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

查看所有标签

猜你喜欢:

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

Effective JavaScript

Effective JavaScript

赫尔曼 (David Herman) / 黄博文、喻杨 / 机械工业出版社 / 2014-1-1 / CNY 49.00

Effective 系列丛书经典著作,亚马逊五星级畅销书,Ecma 的JavaScript 标准化委员会著名专家撰写,JavaScript 语言之父、Mozilla CTO —— Brendan Eich 作序鼎力推荐!作者凭借多年标准化委员会工作和实践经验,深刻辨析JavaScript 的内部运作机制、特性、陷阱和编程最佳实践,将它们高度浓缩为极具实践指导意义的 68 条精华建议。 本书共......一起来看看 《Effective JavaScript》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换