npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

axios-expand

v1.0.8

Published

axios增强。配置式请求路径、本地数据、缓存数据、路径参数、GET,POST参数传递自动判断、请求前后拦截器增强,请求体类型设置等增强封装

Downloads

12

Readme

更新说明

2022-01-12

  • 修复:commonjs导出bug
  • 新增:导出 mergeOptions 方法。此方法可以将多个axios-expand配置进行合并
  • 新增:cache 参数可以设置为一个方法,用于返回自定义缓存标识id
  • 优化:文档更新

2021-12-01

  • 重构:apirequest 方法进行了合并。request 方法现在可以查找接口配置列表中的配置了。而 api 方法只是做为别名使用
  • 新增: generateOptions 方法用于获取配置。并且优化了配置获取的逻辑。
  • 优化:POST请求下本地缓存的id生成逻辑

2021-11-16

  • 新增:before 处理函数返回 false 会中止当前请求
  • 新增:保留了 requestType 参数转换前的原始 data 。可以在 after transformInstance 等处理函数的响应结果的配置的 originalData 字段拿到
  • 优化:requestType 参数的转换逻辑放在 before 执行之后。也就是说能够在 before 中直接拿到转换前的参数
  • 优化:after 处理函数执行顺序放到了 errorIntercepttransformInstance 之后。避免发生异常时依然能够进到 after 处理函数中

2021-10-29

  • 移除: pathParamsReg参数新增pathParam参数。需要自定义路径参数解析使用before参数实现
  • 修复: 某些情况下误报 option.url 参数未设置的bug
  • 优化: requestType参数的设置逻辑

2021-10-25

  • 修复: 模块导出错误的bug
  • 修复: merge函数以及copy函数逻辑错误导致的报错
  • 优化: 配置参数
    • 优化了before after transformInstance参数。多个配置来源都设置了这些参数的时候会依次全部调用
    • 删除了transformBefore参数。使用before参数代替
    • 删除了transformAfter参数。使用after参数代替

简介

对axios进行了如:配置式请求路径、本地数据、缓存数据、路径参数、GET,POST参数传递自动判断、请求前后拦截器增强,请求体类型设置等增强封装。

使用示例

  • 基本
import AxiosExpand from "axios-expand";
const AE = new AxiosExpand();
/*
	method: GET
	url: /api/data?id=1
*/
AE.request("/api/data", { id: 1 });

/*
	method: POST
	url: /api/data
	header: Content-Type: application/json
	body: { id: 1 }
*/
AE.request("/api/data", { id: 1 }, "POST");

/*
	method: POST
	url: /api/data?id=1
	header: application/x-www-form-urlencoded
	body: name=amoamo&age=18
*/
AE.request({
    url: "/api/data",
    method: "POST",
    params: { id: 1 },
    requestType: "form-url", // 请求类型。自动设置对应的Content-Type和格式化数据。
    data: { name: "amoamo", age: 18 }
});
  • 配置路径列表
import AxiosExpand from "axios-expand";

// 路径映射列表
const apis = {
    login: {
        url: "/api/login",
        method: "POST",
    },
    userInfo: "/api/info"
}

// 创建实例并传入初始参数
const AE = new AxiosExpand({
    apis // 注册列表
});

/*
	method: POST
	url: /api/login
	header: Content-Type: application/json
	body: { username: "admin", password: "password" }
*/
let p = AE.request("login", {
    username: "admin",
    password: "password"
})

/*
	method: POST
	url: /api/info?userId=123
*/
p = p.then((res)=> {
  return AE.request({
      api: "userInfo",
      params: { userId: res.data.userId }
  }) 
});

p.then((res)=> {
    console.log(res.data.info)
});
  • 多个选项来源
import AxiosExpand from "axios-expand";
// 1. 全局选项
AxiosExpand.defaults = {
    requestType: "form-url"
}
// 2. 实例选项
const AE = new AxiosExpand({
    apis: {
	    // 3. 请求配置列表选项
        login: {
            url: "/api/login",
            method: "POST"
        }
    },
    after: [function(res){
    	res.$data = res.data.data || {};
	}],
    errorIntercept(res){
    	return res.data.code === 0;
	},
    transformInstance(p) {
        p.catch(res => {
            if (res.$fromErrorIntercept) {
                console.warn(res)
            }else{
                console.error(res);
            }
        })
    }
});
// 4. api 参数选项
AE.api({
    api: "login",
    data: {
        username: "admin",
        password: "password"
    }
}).then(res=> {
    console.log(res.$data)
});

接口说明

AxiosExpand

构建 AxiosExpand 实例的构造方法

构造函数 new AxiosExpand(options)

  • 参数
    • options - 当前实例的全局配置
  • 返回值:一个 AxiosExpand 实例
import AxiosExpand from "axios-expand";
const AE = new AxiosExpand({
    before: [
        function(options){
            console.log(options) // { url: "/api/data", params: { id: 1 }, ... }
        }
    ]
});
AE.request("/api/data", { id: 1 }).then(res=> {...});

静态属性

  • AxiosExpand.defaults 全局的options配置,会影响所有实例

    import AxiosExpand from "axios-expand";
    AxiosExpand.defaults = {
    	requestType: "form-url"
    }
    const AE = new AxiosExpand();
    /*
        method: POST
        url: /api/data
        header: Content-Type: application/x-www-form-urlencoded
        body: id=1&name=amo
    */
    AE.request("/api/data", { id: 1, name: "amo" }, "POST").then(res=> {...});

mergeOptions(...object)

合并多个 options 对象的方法,主要用于二次开发的时候对参数的处理。这个方法主要是进行对象深度合并,但是会区别 before, after, transformInstance 等属性,这些属性的值会合并为一个数组,而不是深度复制的直接覆盖值。

  • 参数
    • 多个需要合并的配置对象,注意只能是对象,不能是字符串
  • 返回值:合并后的对象
import { mergeOptions } from "axios-expand";
const options = mergeOptions(
    {
        api: "login",
        params: {
            a: 10
        },
        before: function(option){
            console.log(1)
        }
    },
    {
        params: {
            b: 20
        },
        data: "data-string",
        before: [function(option){
            console.log(2)
        }]
    },
);

/*
返回值如下
{
    "api": "login",
    "before": [
    	function(option){
            console.log(1)
        },
        function(option){
            console.log(2)
        }
    ],
    "params": {
        "a": 10,
        "b": 20
    },
    "data": "data-string",
}
*/
console.log(options);

AxiosExpand 实例

方法

  • AE.request(options[, params[, method]]) 发起一个请求

    • 参数
      • opitons - 当前请求的完整配置 | 配置列表名称 | 请求路径 url
        • 传入一个 object 作为完整的 options 配置 (具体配置查看后文)
        • 传入一个配置的名称string,也就是 apis 配置项的键
        • 请求路径string
      • params - 当前请求的 params 或者 data。取决于当前方法是 GET 请求还是 POST 请求
        • 如果是 params 则会和 options.params 进行合并
        • 如果是 data 则会判断 options.data 的类型后决定是和合并还是覆盖
      • method - 当前请求的方法。默认为 GET
    • 返回值:返回响应的 promise
    • 此方法做了 bind 处理可以直接赋值调用
    import AxiosExpand from "axios-expand";
    const AE = new AxiosExpand({
        apis: {
            login: {
                url: "/api/login",
                params: {
                    type: "app",
                },
                data: {
                    username: "",
                    password: ""
                }
                method: "POST"
            }
        }
    });
      
    // 可以直接赋值或者模块导出后使用
    const request = AE.request;
      
    // 常规的 optoins 配置
    request({
        api: "login",
        parmas: { type: "web" },
        data: {
            username: "name",
            password: "123456"
        }
    }).then(res=> {});
      
    // 配置名称 - 这种方式无法同时覆盖 params 和 data
    request(
        "login", 
        {
            username: "name",
            password: "123456"
        }
    );
      
    // 请求路径
    request(
        "/api/login?type=app", 
        {
            username: "name",
            password: "123456"
        },
        "POST"
    );
  • AE.api(options[, params[, method]]) 只是一个 request 方法的别名

  • AE.generateOptions(options[, params[, method]]) 返回一个完整的配置对象

    • 参数:和 request 方法参数完全一致
    • 返回值:会从配置列表中查找并且合并、转换后得到的最终配置。 request 方法内部就是使用的此方法
    • 通常用在进行二次封装需要对参数进行处理的时候
    • 用此方法获取的 options 直接传入 request 方法时不会再次处理,会直接被作为最终配置

options

首先,兼容axios所有的原生配置,额外配置都是在其基础上增加的。除了默认导出的是构造函数需要自己构建实例之外,基本可以无差别和axios一样使用。参下:

import Axios from "axios/lib/core/Axios";
class AxiosExpand extends Axios {
    constructor(options) {
        super(
            mergeOptions(
                defaults,
                AxiosExpand.defaults,
                options,
                true
            )
        );
    },
    ......
}

选项来源

最终的 request 方法的选项,可能是多个来源合并后的最终结果。选项可能的来源和合并优先级:

可能来源:
AxiosExpand.defaults     --> 所有实例的默认选项
new AxiosExpand(options) --> 当前实例的默认选项
apis                     --> 路径配置对象中的选项
request(options)         --> request 方法传入的选项

优先级:
AxiosExpand.defaults < new AxiosExpand(options) <  apis < request(options)

选项列表

选项说明

  • apis :选项配置对象,可以使用 request 方法查找此对象中的请求配置来进行请求

    • 类型:object
    • 只能在实例初始化阶段配置
    import AxiosExpand from "axios-expand";
      
    const AE = new AxiosExpand({
        apis: {
            // 一个基本配置选项
            login: {
                url: "/api/login",
                method: "POST",
            },
            // 简写配置选项 等同 { url: "/api/info", method: "POST" }
            userInfo: "/api/info"
        }
    });
      
    const request = AE.request;
      
    request("login", {
        username: "admin",
        password: "password"
    }).then((res)=> {
      return request({
          api: "userInfo",
          params: { userId: res.data.userId },
          data: res.data.token
      }) 
    }).then((res)=> {
        console.log(res.data.info)
    });
  • api :配置对象apis的一个键名。代表需要使用这个配置进行请求

    • 类型:string
    • 只能在 request 方法中使用
    • request 方法的第一个参数为 string 的时候,会优先视为此参数的简写,如果查找不到则会被视为一个请求路径
    import AxiosExpand from "axios-expand";
      
    const AE = new AxiosExpand({
        apis: {
            login: {
                url: "/api/login",
                method: "POST",
            },
            userInfo: "/api/info"
        }
    });
      
    const request = AE.request;
      
    // 简写方式 等同 request({ api: "login", params: { ... } });
    request("login", {
        username: "admin",
        password: "password"
    }).then((res)=> {
      // 常规方式
      return request({
          api: "userInfo",
          params: { userId: res.data.userId },
          data: res.data.token
      }) 
    }).then((res)=> {
        // 设置路径
        request("/api/isInit", { name: res.data.name });
    });
  • url :请求路径

    • 类型:string

    • 新增了路径参数替换功能

      import AxiosExpand from "axios-expand";
          
      const AE = new AxiosExpand({
          apis: {
              userInfo: {
      	        // 使用 :name 的格式设置参数位置
                  url: "/api/info/:userId"
              }
          }
      });
          
      AE.request({
          api: "userInfo",
          params: {
              // 这个参数会被传递给路径
              userId: 123,
              // 其它参数会被保留为查询字符串参数
              type: "web"
          }
      });
      // 转换后最终的 url 格式为: /api/info/123?type=web
          
  • pathParam: 是否开启路径请求参数处理

    • 类型:boolean

    • 默认值:true

    • 禁用后不会自动转换路径参数。可以自己在 before 函数中处理

      import AxiosExpand from "axios-expand";
          
      const AE = new AxiosExpand({
          // 禁用路劲参数
          pathParam: false,
          apis: {
              userInfo: {
      	        // 自定义路径参数格式
                  url: "/api/info/{userId}"
              }
          },
          before: [
      	    // 自定义路径处理逻辑
              function(options){
                  options.url = options.url.replace(/\{(.+)\}/g, function(m, $1){
                      let value = options.params[$1];
                      return value || m;
                  })
              }
          ]
      });
          
  • requestType: 请求类型。会根据类型自动设置请求头的 Content-Type 以及当 dataobject 时会自动转换 data 格式为匹配当前类型的数据格式

    • 类型:string
    • 默认值:json
    • 可选值
      • jsonapplication/json 格式
      • formmultipart/form-data 格式
      • form-urlapplication/x-www-form-urlencoded 格式
    • 只在methodPOST时才有效
    import AxiosExpand from "axios-expand";
      
    const AE = new AxiosExpand({
        apis: {
            login: {
                url: "/api/login",
            	method: "POST"
            }
        }
    });
      
    /*
    	json 格式
      	
    	Content-Type: application/json
    	data: '{"usename":"admin","password":"123456"}'
    */
    AE.request({
        api: "login",
        requestType: "json",
        data: {
            usename: "admin",
            password: "123456"
        }
    });
      
    /*
    	form 格式
      	
    	Content-Type: multipart/form-data
    	data: FormData
    */
    AE.request({
        api: "login",
        requestType: "form",
        data: {
            usename: "admin",
            password: "123456"
        }
    });
      
    /*
    	form-url 格式
      	
    	Content-Type: application/x-www-form-urlencoded
    	data: "usename=admin&password=123456"
    */
    AE.request({
        api: "login",
        requestType: "form-url",
        data: {
            usename: "admin",
            password: "123456"
        }
    });
  • before: 选项合并完成后,发起请求前的处理方法。可以在这里拓展对 options 的处理

    • 类型:function | array<function>
      • 参数:合并完成后的 options
      • 返回值
        • 返回一个 object 时为新的 options
        • 返回 false 会终止当前请求
    • 可以直接修改 options。也可以返回一个新的 options
    • 如果多个配置来源都配置了 before 参数会自动合并为一个数组依次调用
    import AxiosExpand from "axios-expand";
      
    const AE = new AxiosExpand({
        apis: {
            update: "/api/update"
        },
        before: [
            // 登录状态拦截
            function(){
                if(isLogin()){
                   toLogin();
                   return false
                }
            },
            // 设置自定义 headers 字段
            function(options){
        		options.headers = {
                  Authorization: getToken(),
                  ...options.headers,
                };
    		},
            // 返回新 options
            function(options){
        		return {
                    url: options.url
                }
    		}
        ]
    });
      
    AE.request({
        api: "update",
        before(options){
            console.log(options); // 这个处理方法会在最后被调用
        }
    });
  • after: 请求完成后的处理方法。可以在这里对响应进行处理

    • 类型:function | array<function>
      • 参数:请求响应的 response
      • 返回值
        • 返回一个 object 时为新的 response
    • 可以直接修改 response。也可以返回一个新的 response
    • 一般主要是对响应数据的处理
    • response.config 的等同于 options 。所以我们可以在 after 处理函数中通过 options 自定义参数进行不同处理
    • 如果多个配置来源都配置了 after 参数会自动合并为一个数组依次调用
    import AxiosExpand from "axios-expand";
      
    const AE = new AxiosExpand({
        apis: {
            update: {
                url: "/api/update",
                // 自定义参数
            	msg: "更新成功"
            }
        },
        after: [
            // 空数据处理
            function(response){
                if(!response.data){
               		response.data = {};
                }
            },
            // 请求响应,本地提示
            function(response){
                let { msg } = response.config; // 本地配置的消息 response.config 等同于 options
                let { message } = response.data; // 服务器返回的消息
                if(msg){
                   if(message){
                      msg = message;
                   }else if(typeof msg !== "string"){
    	              msg = "操作成功!";
        	       }
                   alert(msg);
                }
    		}
        ]
    });
      
    AE.request({
        api: "update",
        after(response){
            console.log(response); // 这个处理方法会在最后被调用
        }
    });
  • transformInstance: 请求 promise 实例的处理方法。可以在这里捕获异常或者进行 then 处理

    • 类型:function | array<function>
      • 参数:请求的 promise 实例
      • this: 当前 AxiosExpand 实例
      • 返回值
        • undfinednull 的值,则用此值生成新的 promise 实例替换原本的 promise 实例
    • catchthen 接收到的 response 会优先经过 after 的处理
    • 如果多个配置来源都配置了 transformInstance 参数会自动合并为一个数组依次调用
    import AxiosExpand from "axios-expand";
      
    const AE = new AxiosExpand({
        apis: {
            save: {
                url: "/api/save",
                // 局部配置 通常为了封装多个请求
                transformInstance(promise){
                    return promise.then(()=> {
                       return this.request("update");
                    });
                }
            },
            update: "/api/update"
        },
        // 全局配置 通常用于捕获异常
        transformInstance:[
            function(promise) {
                // 捕获全局的异常
                promise.catch((response) => {
                    // 通过自定义参数判断是否需要显示异常消息
                    if (response.config.errorMessage !== false) {
                        const errMsg = response.data.errorMessage || "请求错误";
                        alert(errMsg);
                    }
                });
            }
        ],
    });
      
    AE.request("save").then((res)=> {
        // 这里实际上是 update 请求的结果
    });
  • errorIntercept:错误拦截器。主要用于处理,响应正确,但是业务上请求错误的逻辑

    • 类型: function
      • 参数:请求响应的 response
      • 返回值
        • 返回 true 表示请求错误。会直接执行 throw response。同时 会在 response 对象上新增一个 $fromErrorIntercept: true 的属性,可以用于在 transformInstance 异常捕获中进行判断
    • before 或者 transformInstance 也能做到类似的处理。但是此方法有专门的相关逻辑处理更加便捷
    import AxiosExpand from "axios-expand";
      
    const AE = new AxiosExpand({
        // 进行错误拦截
        errorIntercept(response) {
            let { data, status } = response;
            let code = data.code; // 业务自定义的状态码
            return status > 400 || code !== 100 && code !== 1;
        },
        transformInstance:[
            function(promise) {
                // 捕获异常
                promise.catch((response) => {
                    // 当 response.$fromErrorIntercept = true 则这个异常是来自 errorIntercept 的拦截
                    if (response.$fromErrorIntercept) {
                        // ...
                    }
                });
            }
        ],
    });
  • cache:启用数据缓存。此次请求会优先从缓存中查找,没有则正常请求,并存入缓存。

    • 类型:boolean | function
      • 设置为 ture 会默认使用 url + params + data(object格式) + method 来作为缓存的判断依据,避免在参数复杂的情况下使用
      • 设置为 function 可以自己定义缓存的条件
        • 参数:为 options
        • 返回值:string 自定义缓存请求的 id 的字符串
    • 避免在全局配置中使用此参数
    import AxiosExpand from "axios-expand";
      
    const AE = new AxiosExpand({
        apis: {
            userTypeList: {
                url: "/api/userTypeList",
                cache: true
            }
        }
    });
      
    // 只会产生一次请求
    AE.request("userTypeList"),
    AE.request("userTypeList");
      
  • local: 本地静态数据。设置此参数后不会产生请求,而是使用本地设置的数据来作为响应的数据

    • 类型:any | function
      • 设置为非方法的任意数据时,这个请求 response.data 则指向这条数据
      • 设置为 function 时,会调用这个方法,用方法的返回结果作为这个请求的数据
        • 参数:为 options
    import AxiosExpand from "axios-expand";
      
    const AE = new AxiosExpand({
        apis: {
            localTypeList: {
                local: [
                    { name: "管理员", type: "admin"},
                    { name: "普通用户", type: "user"}
                ]
            }
        }
    });
      
    AE.request("localTypeList").then(response=> {
        /*
        response 是一个简单模拟 response 的对象 
        {
          data: [{ name: "管理员", type: "admin"}, { name: "普通用户", type: "user"}],
          config: options,
          headers: {},
          request: {},
          status: 200,
          statusText: "",
        }
        */ 
        console.log(response);
    })