前言
本文基于Api13。
上篇文章,简单的对rcp中的会话问题做了概述,本篇文章,我们聊一聊rcp中的拦截器问题,按照正常开发,其实拦截器中也不存在问题的,毕竟都是很官方的开发方式,但是在结合了创建会话之后,这个问题就会暴露出来。
声明一个拦截器,打印一下请求传入的头参:
class MyInterceptor implements rcp.Interceptor { intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> { console.log("===拦截器打印headers:" + JSON.stringify(context.request.headers)) return next.handle(context) } }
我们还是用上一篇文章中的案例,简单接收一个headers参数。
private doHttp(headers?: rcp.RequestHeaders) { // 定义sessionConfig对象 const sessionConfig: rcp.SessionConfiguration = { headers: headers, interceptors: [new MyInterceptor()], //拦截器 requestConfiguration: { transfer: { autoRedirect: true, timeout: { connectMs: 10000, transferMs: 10000 }, }, tracing: { verbose: true } } } // 创建通信会话对象 if (this.mSession == undefined) { this.mSession = rcp.createSession(sessionConfig) } // 定义请求对象rep let req = new rcp.Request('xxx', 'GET') // 发起请求 this.mSession.fetch(req).then((response) => { console.log("=======SUCCESS:" + response.toString()) }).catch((err: BusinessError) => { console.log("=======ERROR:" + err.message) }) }
我们发起两次请求,测试一下:
第一次请求
this.doHttp({ "content-type": "application/json" })
第二次请求
this.doHttp({ "content-type": "text/plain" })
看下拦截器中的打印
问题已经很明显了,明明请求头参数做了修改,为什么打印的还是第一次请求中传递的?
问题原因
其实想必,大家一眼就看到了问题,我们在上篇文章中,针对rcp会话做了优化,采取了rcp复用机制,虽然解决了rcp的会话问题,但是由于headers参数是在rcp会话中的传入的,复用,意味着所有的会话配置都进行了复用,这就导致了,一些参数,比如headers就无法更新的问题。
当然了,你可以采用不复用会话,每次会话后直接关闭,但是这种频繁的创建关闭会很消耗资源,当然了,如果你不在乎,也可以这么去做。
问题解决
解决方式也是非常的简单,一些灵活可变的参数,交由Request对象处理,比如headers,cookies等。
let req = new rcp.Request('xxx', 'GET', headers)
还是上边的请求方式,我们再来看下拦截中的打印:
可是发现,拦截中的参数已经发生了变化。
其它问题
很多人都会在拦截器中做很多的操作,比如统一错误处理,日志打印,数据重定向等等,特别是在数据重定向的时候,一定要根据自身的返回类型进行进行赋值,这个是非常重要的,比如那边接收的是json,在数据赋值的时候一定是json,特别是在网络库封装的时候。
如果你只想改变一个json,比如获取前是加密的,解密后再次返回,那么就通过toString,而不是toJSON。
class MyInterceptor implements rcp.Interceptor { async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> { let res = await next.handle(context) let response: rcp.Response = { request: res.request, statusCode: res.statusCode, headers: res.headers, toString: () => "{'name':'程序员一鸣'}", toJSON: () => null } return Promise.resolve(response) } }
在看日志打印:
相关总结
关于rcp的拦截器问题,最重要的就是会话复用的时候,如果Request对象中有需要的参数,就直接用Request中的,而不是使用session中的。