内容简介:提到当然不涉及到项目任何隐私,只是纯粹的技术,对,很纯粹。不直接引用 axios 发送请求,而是统一调用
提到 axios
都不陌生,由之前的 XMLHttpRequest -> $.ajax
-> Fetch 发展,看来 Promise 是趋势,而项目中也是由 vue-resource
的 this.$http
"净化" 成了 axios ,但实际项目中不只是引用 axios 发送请求那么简单,往往还需要进行封装,以下就分享下我们项目中使用 axios 都做了哪些事。
当然不涉及到项目任何隐私,只是纯粹的技术,对,很纯粹。
封装 Service 层
不直接引用 axios 发送请求,而是统一调用 service.js
,在 Service 层里会做很多事。
创建 Serivce
const service = axios.create({ timeout: 10000, headers: { post: { 'Content-Type': 'application/json;charset=UTF-8', }, }, emulateJSON: true, withCredentials: true, });
使用 axios.create
创建一个实例,并且配置一些 JSON 、超时、跨域之类的属性。
国际化
统一使用 service.interceptors.request.use
拦截,并注入国际化标识,比如 request.headers['Accept-Language']
或者 request.params.lang
等。
规范化后端数据结构
在 service.interceptors.response.use
里统一后端返回结构,比如最终会序列化成:
{ success: Boolean, code: Number, message: String, data: Any, }
这样好处是说业务层不需要关心各个服务端返回的是否正确,而规范化后端数据时,需要跟各个服务端沟通好返回的字段标识,以方便来转成规范化结构,比如A端认为 code === 200
才是成功,B端认为 code=0
才是成功。
接口容错
对于前端服务而言,我们认为不应该出现报错到控制台,而应该更友好的展示出来,甚至于把错误信息上报到监控中心,在 Service 对外暴露 POST 、GET 方法时,统一使用 try
拦截,如:
/** * 重构 service 输出,为了兼容接口异常,导致js崩溃 */ export default { async get(...options) { try { const res = await service.get(...options); return res; } catch (e) { return Promise.resolve({ success: false, code: 500, message: '服务出错,请稍候重试', }); } }, async post(...options) { try { const res = await service.post(...options); return res; } catch (e) { return Promise.resolve({ success: false, code: 500, message: '服务出错,请稍候重试', }); } }, };
这样在业务层就可以直接使用数据判断,而不用再 try
或者 .catch
处理,如:
const res = await service.get(uri); // 绝对是成功 if (res.success) { } else { alert(res.message); }
当然这一伟大的逻辑是 @远高 添加,非常厉害。
统一鉴权
因为有规范化后端数据结构,并且结合 service.interceptors.request.use
拦截,可以很方便的对后端鉴权进行处理,比如:A端的A接口返回失败则自动跳转到登录页。甚至可以统一处理帐户的黑、白名单。
URI 统一化
经过以上处理后整个 Service 整个都纵享丝滑,但项目应用时发现:
- 针对某些接口处理事情时比较繁琐,需要不断的向拦截层添加代码
- 接口链接更换时,很依赖全局查找
针对以上的痛点,我们添加了 URI 前缀统一化,处理逻辑是添加一层配置层,把 URI 的前缀使用统一字符替换,如: @a/
、 @b/
这些分别代表不同的接口方,而在使用时可以直接使用这些标识去请求, Service 层会统一处理替换,如:
export const api = { '@a/': { url: 'https://www.demo.com/api/a/', // 自定义统一 headers headers(service.config) { return { }; }, // 自定义统一参数 params(service.config) { return { }; }, // 自定义统一返回值 response(service.config, response) {}, }, };
这样处理后在使用时只需要 service.get('@a/user/mm');
即可,甚至配置里还可以根据当前的环境进行分发到不同的接口中,萌萌哒~
Node.js 代理
Service 层处理之后,如果使用 CORS 即可直接生效,但现在很多服务都是反向代理,可以使用 webpack 的 devServer.proxy
,如:
// config/proxy.js /** * 本地开发、测试配置 * * @type {Object} */ const dev = { '/api/a/': { target: '目标开发环境', changeOrigin: true, onProxyReq(req) { req.setHeader('origin', '目标开发环境'); }, }, }; /** * 线上生产模式 * * @type {Object} */ const prod = { '/api/a/': { target: '目标生产环境', changeOrigin: true, onProxyReq(req) { req.setHeader('origin', '目标生产环境'); }, }, }; // 暴露 dev 代理 exports.dev = dev; // 暴露生产代理 exports.prod = prod; // 根据环境暴露不同的代理 exports.proxy = IS_PROD ? prod : dev;
在 devServer.proxy
直接引用对应的环境配置即可。
你会发现还配置了 onProxyReq
,是因为 changeOrigin
只是会修改请求的 host
,代码见: node-http-proxy
,而很多后端服务是有源 origin
限制,这样就可以穿透了。
注意:Service 是运行在浏览器端,而 Node.js 代理只是本地开发时为了接口方便进行的代理,Service 把 @a/
标识替换成请求本地的绝对链接 /api/a/xxx
(假如不是 CORS 外链域名),然后进入 Node.js 代理,而线上大部分都是 Nginx 做的代理
。
以上所述就是小编给大家介绍的《axios 在项目中的应用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 六大区块链项目入围网络安全技术应用试点示范项目名单
- Swift 面向应用架构开源项目精选
- 把策略模式应用到实际项目中
- 把「模板方法」应用到实际项目中
- 当「SPA」应用遇上了膨胀的项目
- PHP 项目中应用 Beanstalkd 消息队列
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Node.js in Action
Mike Cantelon、Marc Harter、TJ Holowaychuk、Nathan Rajlich / Manning Publications / 2013-11-25 / USD 44.99
* Simplifies web application development * Outlines valuable online resources * Teaches Node.js from the ground up Node.js is an elegant server-side JavaScript development environment perfect for scal......一起来看看 《Node.js in Action》 这本书的介绍吧!