RCP远场通信之拦截器
本文介绍了鸿蒙RCP远场通信中拦截器的使用方法。通过链式拦截器实现请求和响应的修改:1)请求拦截器可在发送前修改URL和请求头,示例演示了基于token的认证处理;2)响应拦截器可检查修改返回结果,并实现状态码判断和弹窗提示。文章提供了完整的拦截器实现代码,包括请求类型判断、token验证、白名单配置等功能,展示了如何通过拦截器实现网络请求的统一管理和错误处理机制。
##鸿蒙核心技术##HarmonyOS SDK应用服务##RCP(远场通信)#
在上一篇文章中介绍了鸿蒙RCP远场通信的基本请求,https://blog.csdn.net/CZC2002/article/details/148195926?spm=1001.2014.3001.5501
在本文中,介绍RCP远场通信的拦截器的使用
1.拦截器的工作原理
客户端发送HTTP请求,到达目标服务器之前,可以使用拦截器对HTTP的请求进行修改。如下图,定义了链式拦截器,RequestUrlChangeInterceptor拦截器(下文以拦截器1代替)和ResponseHeaderRemoveInterceptor拦截器(下文以拦截器2代替)。拦截器1会将请求先拦截,该拦截器可以实现当网络质量差时,通过修改HTTP请求中的URL,来调整请求资源的大小。然后经过拦截器2,最后到达Internet。当请求到达目标服务器,服务器返回请求响应的结果给客户端之前,可以使用拦截器对HTTP的响应进行修改。响应先被拦截器2拦截,在响应返回给应用前检查和修改服务器的请求头。然后经过拦截器1,最后客户端接收响应结果。

请求拦截器的实现(以get请求为例)
先用express写一个get接口
app.get('/api/persons', (req, res) => {
if (req.headers["token"]) {
if (req.headers["token"] == "1234") {
res.status(200).json({
code: 200,
message: "请求成功",
success: true,
data: [{
id: 1,
name: "张三",
age: 20
}]
})
} else {
res.status(601).json({
code: 601,
message: "认证信息有误",
success: false
})
}
res.status(600).json({
code: 600,
message: "请提供认证",
success: false
})
}
})
那么get请求localhost:3000/api/persons这个路径,如果没有token则会收到请提供认证的响应,如果提供了token,但是不是1234那么会受到认证信息有误的响应,只有为1234才是正常的,
我们先写一个基础的请求拦截器

代码如下:
import { rcp } from "@kit.RemoteCommunicationKit";
class requestInterceptorClass {
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
if (context.request.method == "GET") {
console.log("请求方法是get")
}
return next.handle(context);
}
}
export const RequestInterceptor: rcp.SessionConfiguration = {
interceptors: [
new requestInterceptorClass()
],
requestConfiguration: {}
}
在这里我们写了一个简单的请求拦截器,仅仅只对get'请求做了操作,然后如果是get则输出请求方式是get,现在让我们绑定到get中
回到我们的RCPPage文件中
修改rcpGet函数
rcpGet = () => {
const session = rcp.createSession(RequestInterceptor)
session.get(rcpBaseUrl).then((res: rcp.Response) => {
this.showList = (JSON.parse(JSON.stringify(res)) as getReturnModel).data
console.log("res", JSON.stringify(res))
session.close()
}).catch((err: BusinessError) => {
console.log("err", JSON.stringify(err))
})
}
在这里我们绑定了拦截器到session中
整个页面代码
import { rcp } from '@kit.RemoteCommunicationKit';
import { rcpBaseUrl } from '../rcpBaseUrl/rcpBaseUrl';
import { BusinessError } from '@kit.BasicServicesKit';
import { getReturnModel, GetReturnModelData } from '../Model/getReturnModel';
import { postBodyModel } from '../Model/postBodyModel';
import { putBodyModel } from '../Model/putBodyModel';
import { deleteBodyModel } from '../Model/deleteBodyModel';
import { RequestInterceptor } from '../Interceptor/RequestInterceptor';
@Entry
@Component
struct RCPGetPage {
@State message: string = 'Hello World';
@State showList: GetReturnModelData[] = []
@State postName: string = ""
@State putId:string=""
@State putData:string=""
@State deleteId:string=""
rcpGet = () => {
const session = rcp.createSession(RequestInterceptor)
session.get(rcpBaseUrl).then((res: rcp.Response) => {
this.showList = (JSON.parse(JSON.stringify(res)) as getReturnModel).data
console.log("res", JSON.stringify(res))
session.close()
}).catch((err: BusinessError) => {
console.log("err", JSON.stringify(err))
})
}
rcpPost = (name: string) => {
const session = rcp.createSession()
session.post(rcpBaseUrl, { name } as postBodyModel).then((res: rcp.Response) => {
console.log("res", JSON.stringify(res))
session.close()
}).catch((err: BusinessError) => {
console.log("err", JSON.stringify(err))
})
}
rcpPut=(data:putBodyModel)=>{
const session=rcp.createSession()
session.put(rcpBaseUrl,data).then((res: rcp.Response) => {
console.log("res", JSON.stringify(res))
session.close()
}).catch((err: BusinessError) => {
console.log("err", JSON.stringify(err))
})
}
rcpDelete=(data?:deleteBodyModel)=>{
const request = new rcp.Request(`${rcpBaseUrl}`, "DELETE", {
"Content-Type": "application/json"
}, data);
const session=rcp.createSession()
session.fetch(request).then((res: rcp.Response) => {
console.log("header",JSON.stringify(res.headers))
console.log("body",JSON.stringify(res.body))
console.log("res", JSON.stringify(res))
session.close()
}).catch((err: BusinessError) => {
console.log("err", JSON.stringify(err))
})
}
build() {
Column() {
Button("get请求")
.onClick(() => {
this.rcpGet()
})
ForEach(this.showList, (item: GetReturnModelData, index: number) => {
Row() {
Text("id")
Blank().width(40)
Text(item.id.toString())
Blank().width(50)
Text("name")
Blank().width(40)
Text(item.name)
}
}, (item: GetReturnModelData) => JSON.stringify(item))
Divider().height(5).width("100%")
TextInput({ placeholder: "请输入post的名字", text: $$this.postName })
Button("post请求").onClick(() => {
this.rcpPost(this.postName)
})
Divider().height(5).width("100%")
TextInput({placeholder:"请输入put的id",text:$$this.putId})
TextInput({placeholder:"请输入put的名字",text:$$this.putData})
Button("put请求").onClick(()=>{
this.rcpPut({id:this.putId,name:this.putData})
})
Divider().height(5).width("100%")
TextInput({placeholder:"请输入删除的id",text:$$this.deleteId})
Button("delete请求").onClick(()=>{
this.rcpDelete({id:this.deleteId})
})
}
.height('100%')
.width('100%')
}
}
现在我们之间点击get请求按钮,发现控制台输出:

符合我们的预期,现在我们修改拦截器
class requestInterceptorClass {
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
if (context.request.method == "GET") {
context.request.headers={
token:"12345"
}
console.log("请求方法是get")
}
return next.handle(context);
}
}
我们提供token为12345,那么预期输出认证信息不对
我们再点击get按钮

符合我们的预期
那么再修改get请求为正确的
class requestInterceptorClass {
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
if (context.request.method == "GET") {
context.request.headers={
token:"1234"
}
console.log("请求方法是get")
}
return next.handle(context);
}
}
那么就应该输出正常的
发现没问题,模拟器上也正常显示

除此之外,我们可以设置某些url不需要token
代码如下
import { rcp } from "@kit.RemoteCommunicationKit";
const urlArr: string[] = []
class requestInterceptorClass {
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
if (!urlArr.includes(context.request.url.toString())) {
if (context.request.method == "GET") {
context.request.headers = {
token: "1234"
}
console.log("请求方法是get")
}
}
return next.handle(context);
}
}
export const RequestInterceptor: rcp.SessionConfiguration = {
interceptors: [
new requestInterceptorClass()
],
requestConfiguration: {}
}
在定义的urlArr中的url则不添加token
响应拦截器
代码如下:
class responseInterceptorClass {
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
console.log("响应拦截器")
const response = await next.handle(context)
const toReturn: rcp.Response = {
request: response.request,
statusCode: response.statusCode,
headers: {
token: response.headers.token
},
toJSON: () => (response.toJSON())
}
console.log("code",toReturn.statusCode)
if (toReturn.statusCode == 601) {
AlertDialog.show({
message: "认证信息有误"
})
}
if (toReturn.statusCode == 600) {
AlertDialog.show({
message: "请气功认证信息"
})
}
return toReturn
}
}
其中,返回参数的request,statusCode,headers和toJson必传
现在我们修改config
export const RequestInterceptor: rcp.SessionConfiguration = {
interceptors: [
new requestInterceptorClass(),
new responseInterceptorClass()
],
requestConfiguration: {}
}
然后我们修改token为12345
那么会弹出一个认证信息有误的弹窗
点击get按钮

符合我们的预期
现在我们测试不给token,代码如下
class requestInterceptorClass implements rcp.Interceptor{
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
// if (!urlArr.includes(context.request.url.toString())) {
if (context.request.method == "GET") {
// context.request.headers = {
// // token: "1234"
// }
// context.request.headers!["token"]="12345"
console.log("请求方法是get")
}
// }
return next.handle(context);
}
}
点击get按钮:

符合预期,也就是响应拦截器也配置完成
文件目录如下
D:.
│ .clang-format
│ .gitignore
│ build-profile.json5
│ code-linter.json5
│ hvigorfile.ts
│ local.properties
│ oh-package-lock.json5
│ oh-package.json5
│
├─.idea
│ │ .gitignore
│ │ modules.xml
│ │ workspace.xml
│ │
│ ├─.deveco
│ │ │ project.cache.json
│ │ │
│ │ └─module
│ │ entry.cache.json
│ │
│ └─modules
│ │ RCPMessage.iml
│ │
│ └─entry
│ entry.iml
│
├─AppScope
│ │ app.json5
│ │
│ └─resources
│ └─base
│ ├─element
│ │ string.json
│ │
│ └─media
│ background.png
│ foreground.png
│ layered_image.json
│
├─entry
│ │ .gitignore
│ │ build-profile.json5
│ │ hvigorfile.ts
│ │ obfuscation-rules.txt
│ │ oh-package.json5
│ │
│ └─src
│ ├─main
│ │ │ module.json5
│ │ │
│ │ ├─ets
│ │ │ ├─entryability
│ │ │ │ EntryAbility.ets
│ │ │ │
│ │ │ ├─entrybackupability
│ │ │ │ EntryBackupAbility.ets
│ │ │ │
│ │ │ ├─Interceptor
│ │ │ │ RequestInterceptor.ets
│ │ │ │
│ │ │ ├─Model
│ │ │ │ deleteBodyModel.ets
│ │ │ │ getReturnModel.ets
│ │ │ │ postBodyModel.ets
│ │ │ │ putBodyModel.ets
│ │ │ │
│ │ │ ├─pages
│ │ │ │ Index.ets
│ │ │ │ RCPPage.ets
│ │ │ │
│ │ │ └─rcpBaseUrl
│ │ │ rcpBaseUrl.ets
│ │ │
│ │ └─resources
│ │ ├─base
│ │ │ ├─element
│ │ │ │ color.json
│ │ │ │ float.json
│ │ │ │ string.json
│ │ │ │
│ │ │ ├─media
│ │ │ │ background.png
│ │ │ │ foreground.png
│ │ │ │ layered_image.json
│ │ │ │ startIcon.png
│ │ │ │
│ │ │ └─profile
│ │ │ backup_config.json
│ │ │ main_pages.json
│ │ │
│ │ ├─dark
│ │ │ └─element
│ │ │ color.json
│ │ │
│ │ └─rawfile
│ ├─mock
│ │ mock-config.json5
│ │
│ ├─ohosTest
│ │ │ module.json5
│ │ │
│ │ └─ets
│ │ └─test
│ │ Ability.test.ets
│ │ List.test.ets
│ │
│ └─test
│ List.test.ets
│ LocalUnit.test.ets
│
└─hvigor
hvigor-config.json5
最后,拦截器的总体代码如下:
import { rcp } from "@kit.RemoteCommunicationKit";
const urlArr: string[] = []
class requestInterceptorClass implements rcp.Interceptor{
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
// if (!urlArr.includes(context.request.url.toString())) {
if (context.request.method == "GET") {
// context.request.headers = {
// // token: "1234"
// }
// context.request.headers!["token"]="12345"
console.log("请求方法是get")
}
// }
return next.handle(context);
}
}
interface test {
message: string
}
class responseInterceptorClass implements rcp.Interceptor{
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
console.log("响应拦截器")
const response = await next.handle(context)
console.log("response",JSON.stringify(response),JSON.stringify(response.toJSON()))
console.log("header",JSON.stringify(response.headers))
const toReturn: rcp.Response = {
request: response.request,
statusCode: response.statusCode,
headers: Object.keys(response.headers).length ? response.headers : {},
toJSON: () => (response.toJSON())
}
console.log("code", toReturn.statusCode)
if (toReturn.statusCode == 601) {
AlertDialog.show({
message: "认证信息有误"
})
}
if (toReturn.statusCode == 600) {
AlertDialog.show({
message: "请气功认证信息"
})
}
return toReturn
}
}
export const RequestInterceptor: rcp.SessionConfiguration = {
interceptors: [
new requestInterceptorClass(),
new responseInterceptorClass()
],
requestConfiguration: {}
}
更多推荐


所有评论(0)