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

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

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

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


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

查看所有标签

猜你喜欢:

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

B端产品经理必修课

B端产品经理必修课

李宽 / 电子工业出版社 / 2018-9 / 59

《B端产品经理必修课:从业务逻辑到产品构建全攻略》主要讲述了“单个产品管理流程”,以展示B 端产品经理的工作方法及B 端产品的设计方法。《B端产品经理必修课:从业务逻辑到产品构建全攻略》分为三个部分。第一部分主要讲述的是B 端产品经理的工作流程和定义(即单个产品管理流程),以及从事B 端产品经理的职业现状和规划,还包括设计B 端产品时需要了解的指导思想。第二部分是通过各个章节来讲述单个产品管理流程......一起来看看 《B端产品经理必修课》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器