HarmonyOS —— Remote Communication Kit 拦截器(Interceptor)高阶定制能力笔记
摘要: 本文介绍了HarmonyOS Remote Communication Kit中的拦截器(Interceptor)高阶定制能力。拦截器是HTTP请求/响应链路上的中间件,可读取和修改Request/Response,实现统一Header处理、URL动态修改、响应过滤等功能。文章对比了拦截器与ProcessingConfiguration的区别,并指出拦截器支持Phone/2in1/Tabl
HarmonyOS —— Remote Communication Kit 拦截器(Interceptor)高阶定制能力笔记
这个就是 Remote Communication Kit 里“最能折腾”的一层:
配完 DNS / 传输 / 代理 / 安全 / 处理规则之后,再来一层 拦截器链,想怎么改请求/响应都行。
一、拦截器是什么?和前面的配置有什么不一样?
之前你已经看了这些:
DnsConfiguration:改“怎么查 IP”TransferConfiguration:改“超时/重试等传输策略”ProxyConfiguration:改“走不走代理 & 用哪个代理”SecurityConfiguration:改“证书、安全校验”ProcessingConfiguration:改“怎么判定响应成功/失败”
拦截器(Interceptor)则是:
在整个 HTTP 请求/响应链路上,插入一串你自己写的“中间件”,
可以 读取 & 修改 Request / Response,还可以决定“放行 or 拦截”。
它的典型用途比 ProcessingConfiguration 更“野”:
- 在请求发出去前:
- 给所有请求加上统一 Header(如 Token、Trace-Id)
- 动态改 URL、Host、Query、Body 等
- 在响应回到业务前:
- 统一处理/过滤/脱敏 Header
- 在本地做缓存、Mock 返回
- 打点、日志、A/B 实验埋点
ProcessingConfiguration 更像:
“我只看响应,帮你判断成功/失败。”
拦截器更像:
“我可以改请求、改响应,还能串成一个链,按顺序执行。”
二、设备 & 版本限制(老熟人)
和前面所有配置一样:
- 支持设备:Phone / 2in1 / Tablet / Wearable
- 自 5.1.1(19) 起:新增支持 TV
一句话背:
拦截器能力支持 Phone / 2in1 / Tablet / Wearable,5.1.1(19) 起新增 TV 支持。
三、拦截器工作原理(链式执行)
文档里的示例设定了两个拦截器:
RequestUrlChangeInterceptor(下面叫:拦截器 1)ResponseHeaderRemoveInterceptor(下面叫:拦截器 2)
请求方向:
- 应用代码发起请求 → 先进入拦截器 1
- 拦截器 1 可以改 URL(例如从
xxx.png改成xxx_small.png) - 再进入拦截器 2,可以继续改 Request
- 最后才真正发到 Internet/服务器
响应方向:
- 服务器返回 Response → 先被拦截器 2 截获
- 拦截器 2 可以改响应头、改响应体
- 再走到拦截器 1
- 最终才送到你的业务代码
顺序记忆:
- 请求:按数组顺序执行(1 → 2 → … → 真正网络)
- 响应:按逆序执行(… → 2 → 1 → 业务)
而且这些拦截器都是你自己通过类实现的:
实现 rcp.Interceptor 接口,在 intercept(context, next) 里编写逻辑。
四、示例 1:根据网络质量动态改图片 URL
1. 模拟网络质量 — NetworkQualityProvider
export class NetworkQualityProvider {
isNetworkFast: boolean = true
public constructor(isNetworkFast: boolean) {
this.isNetworkFast = isNetworkFast
}
}
很简单:通过 isNetworkFast 来模拟网络好/差。
真实项目里,你可以用测速、信号强度、历史统计等来设置这个值。
2. RequestUrlChangeInterceptor:慢网改成“小图”
export class RequestUrlChangeInterceptor implements rcp.Interceptor {
private readonly networkQualityProvider: NetworkQualityProvider;
constructor(networkQualityProvider: NetworkQualityProvider) {
this.networkQualityProvider = networkQualityProvider;
}
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
if (context.request.method === 'GET' && !this.networkQualityProvider.isNetworkFast) {
console.info('[RequestUrlChangeInterceptor]: Slow network is detected');
const parts = context.request.url.pathname.split('.');
if (parts.length === 2) {
const changed = url.URL.parseURL(context.request.url.href);
changed.pathname = parts[0] + '_small.' + parts[1];
console.info(`[RequestUrlChangeInterceptor]: Replace URL from "${context.request.url.href}" to "${changed}"`);
AppStorage.setOrCreate('ReplacedInfo',
`[RequestUrlChangeInterceptor]: Replace URL from "${context.request.url.href}" to "${changed}"`);
context.request.url = changed;
}
} else {
console.info('[RequestUrlChangeInterceptor]: Network is fast');
}
return next.handle(context);
}
}
拆一下它在干嘛:
-
只处理 GET 请求,且网络不快时才介入:
if (context.request.method === 'GET' && !this.networkQualityProvider.isNetworkFast) { ... } -
拿到当前 URL 的
pathname,按.切开拿扩展名:- 比如
/images/banner.png→['/images/banner', 'png']
- 比如
-
用
url.URL.parseURL克隆出一个可变 URL 对象:const changed = url.URL.parseURL(context.request.url.href); changed.pathname = parts[0] + '_small.' + parts[1]; // 变成 /images/banner_small.png -
把替换信息写入
AppStorage(方便 UI 展示或调试) -
将改好的 URL 回写:
context.request.url = changed; -
最后别忘了放行:
return next.handle(context);
核心场景:
网络差时自动改用“小图 / 低清资源”,保证体验。
五、示例 2:ResponseHeaderRemoveInterceptor —— 过滤响应头
export class ResponseHeaderRemoveInterceptor implements rcp.Interceptor {
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
const response = await next.handle(context);
const toReturn: rcp.Response = {
request: response.request,
statusCode: response.statusCode,
httpVersion: response.httpVersion,
headers: {
'content-range': response.headers['content-range']
},
effectiveUrl: response.effectiveUrl,
timeInfo: response.timeInfo,
toJSON: () => null
};
console.info('[ResponseHeaderRemoveInterceptor]: Response was modified');
return toReturn;
}
}
做了两件事:
-
等下游(后面的拦截器 / 真正请求)返回
response:const response = await next.handle(context); -
构造一个新的
rcp.Response对象:-
把原有的
request / statusCode / httpVersion / effectiveUrl / timeInfo原样拷贝; -
只保留
content-range这个响应头,其它 Header 都“清空”:headers: { 'content-range': response.headers['content-range'] },
-
-
记录日志,返回新的响应。
场景理解:
做一层统一的 Header 过滤 / 脱敏,比如在日志系统或下游模块只希望看到部分字段。
六、如何把拦截器挂到 Session 上?
拦截器是在 SessionConfiguration 里配置的:
function httpRequest(networkStateSimulator: NetworkQualityProvider) {
const sessionConfig: rcp.SessionConfiguration = {
interceptors: [
new RequestUrlChangeInterceptor(networkStateSimulator),
new ResponseHeaderRemoveInterceptor()
],
requestConfiguration: {
security: {
tlsOptions: {
tlsVersion: 'TlsV1.3'
}
}
}
};
const session = rcp.createSession(sessionConfig);
}
关键点:
interceptors是一个数组:- 前面的对“请求”先执行,对“响应”后执行(链式正向/反向)
- 拦截器和其它配置(
security.tlsOptions等)可以一起用
你后续通过这个 session 发出的所有请求,都自动带上这两个拦截器。
七、你还可以用拦截器做什么?
几条你以后写博客/出题/实战可以用的思路:
- 统一加 Header:
- 比如每个请求自动带上
Authorization、X-Trace-Id、X-App-Version等
- 比如每个请求自动带上
- 统一改 Host / Base URL:
- 做灰度/多机房切换:写一个
EnvSwitchInterceptor来动态决定请求真正打到哪里。
- 做灰度/多机房切换:写一个
- 本地 Mock:
- 某些特定 URL,干脆不往网络发,直接在拦截器里返回一份假
rcp.Response。
- 某些特定 URL,干脆不往网络发,直接在拦截器里返回一份假
- 重试 / 限流 / 熔断:
- 在拦截器里检测响应错误码(如 5xx),决定是否再次
next.handle(context)。
- 在拦截器里检测响应错误码(如 5xx),决定是否再次
- 日志 & 埋点:
- 所有请求/响应统一在拦截器里打印或上报埋点。
八、最后给你一份“考点速记版”
-
作用:
- 拦截并修改 HTTP 请求 & 响应,支持链式拦截器。
-
核心接口:
interface Interceptor { intercept(context: RequestContext, next: RequestHandler): Promise<Response>; }context.request:可读可改(URL、Header、Body 等)next.handle(context):把请求传给下一个拦截器/网络层Response:可重新构造后返回
-
链路顺序:
- 请求:
interceptors[0] → interceptors[1] → ... → 网络 - 响应:
网络 → ... → interceptors[1] → interceptors[0]
- 请求:
-
设备支持:
- Phone / 2in1 / Tablet / Wearable
- 自 5.1.1(19) 起支持 TV
更多推荐



所有评论(0)