{"_id":"x-axios-helper","_rev":"1-adffb9c699e1b281aeb9ca7ddc636a4f","name":"x-axios-helper","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"x-axios-helper","description":"基于axios扩展的异步请求插件，为前端实现API统一管理的解决方案。","version":"1.0.0","author":{"name":"undefined100","email":"946424684@qq.com"},"license":"MIT","private":false,"main":"dist/x-axios-helper.js","scripts":{"dev":"cross-env NODE_ENV=development webpack-dev-server --open --hot","build":"cross-env NODE_ENV=production webpack --progress --hide-modules","lint":"eslint --ext .js src","fix":"npm run lint -- --fix"},"repository":{"type":"git","url":"git+https://github.com/Undefined100/x-axios-helper.git"},"dependencies":{"axios":"^0.19.2","nprogress":"^0.2.0","promise.prototype.finally":"^3.0.1","qs":"^6.5.1"},"browserslist":["> 1%","last 2 versions","not ie <= 8"],"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^8.2.1","babel-loader":"^7.1.2","babel-preset-env":"^1.6.0","babel-preset-stage-3":"^6.24.1","cross-env":"^5.0.5","css-loader":"^0.28.7","eslint":"^4.15.0","eslint-config-standard":"^11.0.0-beta.0","eslint-friendly-formatter":"^3.0.0","eslint-loader":"^1.9.0","eslint-plugin-html":"^4.0.1","eslint-plugin-import":"^2.8.0","eslint-plugin-node":"^5.2.1","eslint-plugin-promise":"^3.6.0","eslint-plugin-standard":"^3.0.1","file-loader":"^1.1.4","webpack":"^3.6.0","webpack-dev-server":"^2.9.1"},"gitHead":"46b148a72ed63a1a37beb011f4cb507846aeb020","bugs":{"url":"https://github.com/Undefined100/x-axios-helper/issues"},"homepage":"https://github.com/Undefined100/x-axios-helper#readme","_id":"x-axios-helper@1.0.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.1","_npmUser":{"name":"undefined100","email":"946424684@qq.com"},"dist":{"integrity":"sha512-7ME3lSfii1kTr5cqui3s9qlkeWZ92Mu2nxP9R2uFmn2D+me9P81dpXexyH57w1JIb1N5SzntUU5mRaQAVJ2yiw==","shasum":"68891917025c871ae2b90a4e08bfb13606e5dbbc","tarball":"https://registry.npmjs.org/x-axios-helper/-/x-axios-helper-1.0.0.tgz","fileCount":11,"unpackedSize":78054,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelpJXCRA9TVsSAnZWagAAppYP/R0yXTxZa8NsD2EdVe28\nRWlmtZZ1AUwjcdVcQCkjyGKutM1NNheoZyzaA3OXcIgcQ9BXd5Tch2zkwYR7\n3gC6AuAbc56qpVU2ZBfsbt0J1gtP8HIGNlGuamQWUe/N8E+DYK9JNERDor8n\njH26iq74snmQhwMYONOsZ9NJTiWUyK7Btl4vqfs/DBKzYIxvoMes/N2BpjRX\nniq3hlZDwrkSB/jjY39e1U7t6D00fbHXqm2wYrWaxgi+GrJHttPsbLPw+/w/\ntZvU93lyGB2dJaSRQI0SNGo505UWjPlyvYjk+tVBX7Se/vTbiht0KyvCuBmp\nUXDGp3sVQVXrIZUs2P4qdbVXyqDLHxvOzKKwVUf8jLAhWmFGuiKhOyj0QkQH\nz0sRMunxN+WdiofAFuHRY7hmJWma3HJJypk+HkQirfYKP/Qp4/pxFnQrgYOP\nuh9SQlVBhSw0S+VBi4n32Q2FfPQnJxmU9Haj1ZA8emm3mSg2FRHwh8nNj9Ys\npgIBTfmiQekWdwey8MkT5osnkxpXL6rjUZj+HFf2EpNdjlt66E0jmuEa3sg/\nTn5uNpHtTqaP5Ei37jTNep5fZKDZsnoGT0t2jODBz15wTjgTjoT6neHQaTCQ\nro8VyI9o+GbkWb49So6cFQvgHI3pC2d6huI1MohnxgruX+RFT1OFJ8HYB2Lz\nRJ0D\r\n=7FME\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC05mZ4ev7DqzxSK2GQ3ZoabyhJxVFBLrumOfmeiOvjJgIhAODSDbxMHTDgHTczE5qQ/K5YUA32Vczl0S+rC4zvchA3"}]},"maintainers":[{"name":"undefined100","email":"946424684@qq.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/x-axios-helper_1.0.0_1586926167163_0.47819002569423086"},"_hasShrinkwrap":false}},"time":{"created":"2020-04-15T04:49:27.163Z","1.0.0":"2020-04-15T04:49:27.328Z","modified":"2022-05-24T20:54:53.299Z"},"maintainers":[{"name":"undefined100","email":"946424684@qq.com"}],"description":"基于axios扩展的异步请求插件，为前端实现API统一管理的解决方案。","homepage":"https://github.com/Undefined100/x-axios-helper#readme","repository":{"type":"git","url":"git+https://github.com/Undefined100/x-axios-helper.git"},"author":{"name":"undefined100","email":"946424684@qq.com"},"bugs":{"url":"https://github.com/Undefined100/x-axios-helper/issues"},"license":"MIT","readme":"# x-axios-helper\r\n\r\n> 基于axios扩展的异步请求插件，为前端实现API统一管理的解决方案。。\r\n\r\n## 安装\r\n\r\n```Bash\r\nnpm install x-axios-helper --save\r\n```\r\n\r\n## 注册\r\n\r\n在应用入口文件，通过apiHelper进行初始化，使用方式如：\r\n\r\n```js\r\nimport axiosHelper from 'x-axios-helper'\r\n\r\naxiosHelper.register({\r\n  systemConfig: {\r\n    // globalAxiosOptions配置与axios配置一致，axios配置参考axios配置一节\r\n    globalAxiosOptions: {\r\n      baseURL: 'https://some-domain.com/api/',\r\n      ...\r\n    },\r\n    // 系统API配置信息\r\n    api: [{\r\n      name: '通用查询接口',\r\n      method: 'queryData',\r\n      url: '/api/v1/basic/queryData'\r\n    }, {\r\n      name: '通用查询分页接口',\r\n      method: 'pagingData',\r\n      url: '/api/v1/basic/pagingData',\r\n      type: 'get'\r\n    }, {\r\n      name: '通用新增接口',\r\n      method: 'add',\r\n      url: '/api/v1/basic/execute',\r\n      type: 'post',\r\n      /*静态参数*/\r\n      data:{\r\n        lcontent:'测试数据' //请求体参数\r\n      }，\r\n      params:{\r\n        key:'i_s_sys_log'// url参数\r\n      }\r\n    }, {\r\n      name: '路径参数型接口',\r\n      method: 'getUser',\r\n      url: '/api/v1/getUser/{id}'\r\n    }]\r\n  },\r\n\r\n  // 请求拦截器\r\n  requestIntercept(config){\r\n    // 自定义处理逻辑\r\n    return config\r\n  },\r\n\r\n  // 响应拦截器\r\n  responseSuccIntercept(resp){\r\n    // 自定义处理逻辑\r\n    return resp\r\n  },\r\n\r\n  // 响应异常拦截器\r\n  responseErrorIntercept(err){\r\n    // 自定义处理逻辑\r\n  }\r\n).then(() => {\r\n  // 后续逻辑，如启动应用\r\n})\r\n```\r\n\r\n如果要禁用默认的请求拦截器、响应拦截器、响应异常拦截器逻辑，则传入null即可，如下：\r\n\r\n```js\r\nimport axiosHelper from 'x-axios-helper'\r\n\r\naxiosHelper.register({\r\n  ...\r\n  requestIntercept: null,\r\n  responseSuccIntercept: null,\r\n  responseErrorIntercept: null\r\n}).then(() => {\r\n  ...\r\n})\r\n```\r\n\r\n### 最佳实践\r\n\r\n1、将API的配置按模块分别配置，然后统一在一个文件中进行导出\r\n2、在注册异步请求插件的地方，将API配置文件引入进行注册，如：\r\n```\r\n├── src\r\n│   ├── api.js // 接口配置文件\r\n│   ├── main.js\r\n```\r\napi.js文件内容，如下：\r\n\r\n```js\r\nexport default\r\n[{\r\n  name: '通用查询接口',\r\n  method: 'queryData',\r\n  url: '/api/v1/basic/queryData'\r\n}, {\r\n  name: '通用查询分页接口',\r\n  method: 'pagingData',\r\n  url: '/api/v1/basic/pagingData',\r\n  type: 'get'\r\n}, {\r\n  name: '通用新增接口',\r\n  method: 'add',\r\n  url: '/api/v1/basic/execute',\r\n  type: 'post',\r\n  /*静态参数*/\r\n  data:{\r\n    lcontent:'测试数据' //请求体参数\r\n  }，\r\n  params:{\r\n    key:'i_s_sys_log'// url参数\r\n  }\r\n}, {\r\n  name: '路径参数型接口',\r\n  method: 'getUser',\r\n  url: '/api/v1/getUser/{id}'\r\n}]\r\n```\r\n\r\n在入口文件main.js文件中\r\n```js\r\nimport apiConfig from './api'\r\nimport axiosHelper from 'x-axios-helper'\r\n\r\naxiosHelper.register({\r\n  systemConfig: {\r\n    ...\r\n    api: apiConfig\r\n  },\r\n  ...\r\n).then(() => {\r\n  ...\r\n})\r\n```\r\n\r\n## 使用方式\r\n\r\n> 注册后，通过全局变量$api（注册到window对象上）来调用。\r\n\r\n### 配置型接口请求\r\n\r\n> 在注册的地方需要将api配置传入，比如根据以上传入的API配置信息，就可以使用以下方式调用：\r\n\r\n```js\r\n// 使用方式\r\n$api.queryData({\r\n  // 与axios配置一致\r\n  params: {\r\n    key: 's_sys_menu_list',\r\n    page_id: 90,\r\n    user_id: 0\r\n  }\r\n}).then((resp) => {\r\n  console.log(resp)\r\n}).catch(err => {\r\n  console.log(err)\r\n}).finally(() => {\r\n  console.log('done')\r\n})\r\n\r\n$api.pagingData({}).then().catch().finally()\r\n```\r\n\r\n### restful请求\r\n\r\n> 在配置型接口基础上，会默认扩展一种路径参数型请求，通过对应方法的restful方法发起请求，并将匹配到的params参数替换到url路径上，未匹配到的参数拼接到url参数上，比如获取用户接口注册为：\r\n```js\r\n[{\r\n  name: '路径参数型接口',\r\n  method: 'getUser',\r\n  url: '/api/v1/getUser/{id}'\r\n}]\r\n```\r\n\r\n则可发起以下调用：\r\n```js\r\n// 使用方式\r\n$api.getUser.restful({\r\n  // 与axios配置一致\r\n  params: {\r\n    id: 1,\r\n    age: 18\r\n  }\r\n}).then((resp) => {\r\n  console.log(resp)\r\n}).catch(err => {\r\n  console.log(err)\r\n}).finally(() => {\r\n  console.log('done')\r\n})\r\n```\r\n\r\n最终发起的请求为：/api/v1/getUser/1?age=18，以满足后端接口通过路径来接收参数的场景。\r\n\r\n### 语义化请求\r\n\r\n```js\r\n// Get请求\r\n$api.get({\r\n  // 与axios配置一致\r\n  url: '/api/v2/basic/data',\r\n  params: {\r\n    key: 's_sys_menu_list',\r\n    page_id: 90,\r\n    user_id:0\r\n  }\r\n}).then(resp => {\r\n  console.log(resp)\r\n}).catch(err=>{\r\n  console.log(err)\r\n}).finally(() => {\r\n  console.log('done')\r\n})\r\n\r\n// Post请求\r\n$api.post({}).then().catch().finally()\r\n// Delete请求\r\n$api.delete({}).then().catch().finally()\r\n// Put请求\r\n$api.put({}).then().catch().finally()\r\n```\r\n\r\n### 链式请求\r\n\r\n> 当一个接口需要另一个接口的返回值时，则链式请求就可以派上用场，使用方式如下：\r\n\r\n```js\r\n$api.queryData({\r\n  params: {\r\n    key: 'select_sys_menu_list',\r\n    page_id: 90,\r\n    user_id: 0\r\n  }\r\n}).then(resp => {\r\n  // resp即第一个接口返回的结果\r\n  return $api.pagingData({\r\n    params: {\r\n      key: 'i_s_sys_log',\r\n    }\r\n  })\r\n}).then(resp => {\r\n  // resp即第二个接口返回的结果\r\n  return $api.add({\r\n    data: {\r\n      menu:resp.data.data,\r\n      lcontent: '页面访问量'\r\n    }\r\n  })\r\n}).then(resp => {\r\n  console.log(resp)\r\n})\r\n```\r\n\r\n### 并发请求\r\n\r\n```js\r\nconst request1 = () => {\r\n  return $api.add({\r\n    params: {\r\n      key: 'i_s_sys_log'\r\n    },\r\n    data: {\r\n      lcontent: '页面访问量'\r\n    }\r\n  })\r\n}\r\nconst request2 = () => {\r\n  return $api.queryData({\r\n    params: {\r\n      key: 's_sys_menu_list',\r\n      page_id: 90,\r\n      user_id: 0\r\n    }\r\n  })\r\n}\r\n\r\n$api([request1, request2]).then(([resp1,resp2]) => {\r\n  // 多个请求都完成时，才会调用then的回调\r\n  // resp1即request1的响应结果，resp2即request2的响应结果，顺序与传入的请求顺序保持一致\r\n  console.log(resp1)\r\n  console.log(resp2)\r\n})\r\n```\r\n\r\n### 取消请求\r\n\r\n```js\r\n// 取消所有发起的请求\r\n$api.cancel()\r\n\r\n//取消指定的请求\r\n$api.get({\r\n  name:'s_sys_user_list',\r\n  ...\r\n}\r\n}).then()\r\n//发起请求的时候，指定name属性，取消请求的时候，就用name属性值来取消请求\r\n$api.cancel('s_sys_user_list')\r\n\r\n//第二个参数作为提示信息显示在控制台\r\n$api.cancel('s_sys_user_list','取消了用户接口的请求')\r\n```\r\n\r\n### 上传文件\r\n\r\n```js\r\nconst formData = new FormData()\r\nformData.append('userfile', fileInputElement.files[0])\r\n$api({\r\n  // 与axios配置一致，会合并全局配置参数globalAxiosOptions\r\n  method: 'post',\r\n  url: '/api/v1/file/upload',\r\n  // 请求体方式传参\r\n  data: formData\r\n}).then(resp => {\r\n  // 请求成功，执行then的回调\r\n  console.log(resp)\r\n}).catch(err => {\r\n  // 请求发生异常时，你可以在catch的回调里处理\r\n  console.log(err)\r\n}).finally(() => {\r\n  // 无论请求是否成功，都会执行finally的回调\r\n  console.log('done')\r\n})\r\n```\r\n\r\n## token机制\r\n\r\n> 实现思路：在注册插件时，注册请求拦截器和响应异常拦截器，在请求拦截器里给请求头设置token，在响应异常拦截器里处理token过期时的逻辑\r\n\r\n```js\r\nimport axiosHelper from 'x-axios-helper'\r\n\r\naxiosHelper.register({\r\n  ...\r\n  // 请求拦截器\r\n  requestIntercept(config){\r\n    config.headers['Authorization'] = `Bearer token值`\r\n    return config\r\n  },\r\n\r\n  // 响应异常拦截器\r\n  responseErrorIntercept(err){\r\n    if (error.response.status === 401) {\r\n      // token过期，自动跳到登录路由\r\n    }\r\n  }\r\n).then(() => {\r\n  ...\r\n})\r\n```\r\n\r\n## 附：官方axios完整配置参考\r\n\r\n```js\r\n{\r\n  // `url` 是用于请求的服务器 URL\r\n  url: '/user',\r\n\r\n  // `method` 是创建请求时使用的方法\r\n  method: 'get', // 默认是 get\r\n\r\n  // `baseURL` 将自动加在 `url` 前面，除非 `url` 是一个绝对 URL。\r\n  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL\r\n  baseURL: 'https://some-domain.com/api/',\r\n\r\n  // `transformRequest` 允许在向服务器发送前，修改请求数据\r\n  // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法\r\n  // 后面数组中的函数必须返回一个字符串，或 ArrayBuffer，或 Stream\r\n  transformRequest: [function (data) {\r\n    // 对 data 进行任意转换处理\r\n\r\n    return data;\r\n  }],\r\n\r\n  // `transformResponse` 在传递给 then/catch 前，允许修改响应数据\r\n  transformResponse: [function (data) {\r\n    // 对 data 进行任意转换处理\r\n\r\n    return data;\r\n  }],\r\n\r\n  // `headers` 是即将被发送的自定义请求头\r\n  headers: {'X-Requested-With': 'XMLHttpRequest'},\r\n\r\n  // `params` 是即将与请求一起发送的 URL 参数\r\n  // 必须是一个无格式对象(plain object)或 URLSearchParams 对象\r\n  params: {\r\n    ID: 12345\r\n  },\r\n\r\n  // `paramsSerializer` 是一个负责 `params` 序列化的函数\r\n  // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)\r\n  paramsSerializer: function(params) {\r\n    return Qs.stringify(params, {arrayFormat: 'brackets'})\r\n  },\r\n\r\n  // `data` 是作为请求主体被发送的数据\r\n  // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'\r\n  // 在没有设置 `transformRequest` 时，必须是以下类型之一：\r\n  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams\r\n  // - 浏览器专属：FormData, File, Blob\r\n  // - Node 专属： Stream\r\n  data: {\r\n    firstName: 'Fred'\r\n  },\r\n\r\n  // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)\r\n  // 如果请求话费了超过 `timeout` 的时间，请求将被中断\r\n  timeout: 1000,\r\n\r\n  // `withCredentials` 表示跨域请求时是否需要使用凭证\r\n  withCredentials: false, // 默认的\r\n\r\n  // `adapter` 允许自定义处理请求，以使测试更轻松\r\n  // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).\r\n  adapter: function (config) {\r\n    /* ... */\r\n  },\r\n\r\n  // `auth` 表示应该使用 HTTP 基础验证，并提供凭据\r\n  // 这将设置一个 `Authorization` 头，覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头\r\n  auth: {\r\n    username: 'janedoe',\r\n    password: 's00pers3cret'\r\n  },\r\n\r\n  // `responseType` 表示服务器响应的数据类型，可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'\r\n  responseType: 'json', // 默认的\r\n\r\n  // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称\r\n  xsrfCookieName: 'XSRF-TOKEN', // default\r\n\r\n  // `xsrfHeaderName` 是承载 xsrf token 的值的 HTTP 头的名称\r\n  xsrfHeaderName: 'X-XSRF-TOKEN', // 默认的\r\n\r\n  // `onUploadProgress` 允许为上传处理进度事件\r\n  onUploadProgress: function (progressEvent) {\r\n    // 对原生进度事件的处理\r\n  },\r\n\r\n  // `onDownloadProgress` 允许为下载处理进度事件\r\n  onDownloadProgress: function (progressEvent) {\r\n    // 对原生进度事件的处理\r\n  },\r\n\r\n  // `maxContentLength` 定义允许的响应内容的最大尺寸\r\n  maxContentLength: 2000,\r\n\r\n  // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject  promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`)，promise 将被 resolve; 否则，promise 将被 rejecte\r\n  validateStatus: function (status) {\r\n    return status >= 200 && status < 300; // 默认的\r\n  },\r\n\r\n  // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目\r\n  // 如果设置为0，将不会 follow 任何重定向\r\n  maxRedirects: 5, // 默认的\r\n\r\n  // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项：\r\n  // `keepAlive` 默认没有启用\r\n  httpAgent: new http.Agent({ keepAlive: true }),\r\n  httpsAgent: new https.Agent({ keepAlive: true }),\r\n\r\n  // 'proxy' 定义代理服务器的主机名称和端口\r\n  // `auth` 表示 HTTP 基础验证应当用于连接代理，并提供凭据\r\n  // 这将会设置一个 `Proxy-Authorization` 头，覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。\r\n  proxy: {\r\n    host: '127.0.0.1',\r\n    port: 9000,\r\n    auth: : {\r\n      username: 'mikeymike',\r\n      password: 'rapunz3l'\r\n    }\r\n  },\r\n\r\n  // `cancelToken` 指定用于取消请求的 cancel token\r\n  // （查看后面的 Cancellation 这节了解更多）\r\n  cancelToken: new CancelToken(function (cancel) {\r\n  })\r\n}\r\n```\r\n\r\n## 更新日志\r\n- 1.0.0 版本发布","readmeFilename":"README.md"}