欢迎光临
我们一直在努力

HarmonyOS ArkWeb 系列之自定义响应数据:onInterceptRequest 同步与异步两种方式

文章目录

    • 大白话讲两种方式的区别
    • 流程图
    • 方式一:同步返回自定义 HTML
    • 方式二:同步拦截 + $rawfile 返回本地文件
    • 方式三:异步返回(适合读大文件或异步数据)
    • 三种方式对比

有时候需要拦截网页某个请求,返回自定义的数据而不走网络。onInterceptRequest 提供了同步和异步两种方式。

大白话讲两种方式的区别

同步方式:拦截到请求后,立刻准备好数据,直接返回 WebResourceResponse。适合数据已在内存中的场景。

异步方式:先返回一个"占位符" Response(含 ResponseDataID),后台异步准备数据,准备好了再通过 ID 填入。适合读文件、网络请求等耗时操作。

流程图

方式一:同步返回自定义 HTML

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct SyncInterceptPage {
controller: webview.WebviewController = new webview.WebviewController();

@State webData: string =
'<!DOCTYPE html>\\n' +
'<html>\\n' +
'<head>\\n' +
'<title>intercept test</title>\\n' +
'</head>\\n' +
'<body>\\n' +
'<h1>intercept ok</h1>\\n' +
'</body>\\n' +
'</html>';

build() {
Column() {
Web({ src: 'https://www.example.com', controller: this.controller })
.onInterceptRequest((event) => {
if (!event) return null;
const url = event.request.getRequestUrl();

if (url === 'https://www.example.com/') {
const response = new WebResourceResponse();
response.setResponseData(this.webData);
response.setResponseHeader([
{ headerKey: 'Connection', headerValue: 'keep-alive' },
{ headerKey: 'Cache-Control', headerValue: 'no-cache' },
]);
response.setResponseEncoding('utf-8');
response.setResponseMimeType('text/html');
response.setResponseCode(200);
response.setReasonMessage('OK');
return response;
}
return null;
})
.width('100%')
.height('100%')
}
}
}

方式二:同步拦截 + $rawfile 返回本地文件

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct ResourceInterceptPage {
controller: webview.WebviewController = new webview.WebviewController();

build() {
Column() {
Web({ src: 'https://www.example.com', controller: this.controller })
.onInterceptRequest((event) => {
if (!event) return null;
const url = event.request.getRequestUrl();

// 将线上 JS 替换为本地 rawfile 版本
if (url === 'https://www.example.com/assets/framework.js') {
const response = new WebResourceResponse();
response.setResponseData($rawfile('framework.js'));
response.setResponseEncoding('utf-8');
response.setResponseMimeType('application/javascript');
response.setResponseCode(200);
response.setReasonMessage('OK');
return response;
}
return null;
})
.width('100%')
.height('100%')
}
}
}

方式三:异步返回(适合读大文件或异步数据)

import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct AsyncInterceptPage {
controller: webview.WebviewController = new webview.WebviewController();

private async loadLocalFile(filename: string): Promise<string> {
try {
const rm = this.getUIContext().getHostContext()!.resourceManager;
const content = await rm.getRawFileContent(filename);
return new TextDecoder('utf-8').decode(content);
} catch (e) {
console.error('读取文件失败:', (e as BusinessError).message);
return '';
}
}

build() {
Column() {
Web({ src: 'https://www.example.com', controller: this.controller })
.onInterceptRequest((event) => {
if (!event) return null;
const url = event.request.getRequestUrl();

if (url === 'https://www.example.com/data.json') {
const response = new WebResourceResponse();
// 生成唯一 ID,告诉引擎数据稍后填入
const id = response.setResponseDataID();

// 后台异步加载,完成后通过 ID 填入
this.loadLocalFile('data.json').then((content) => {
try {
this.controller.setResponseData(id, content);
} catch (e) {
console.error('setResponseData 失败:', (e as BusinessError).message);
}
});

response.setResponseEncoding('utf-8');
response.setResponseMimeType('application/json');
response.setResponseCode(200);
response.setReasonMessage('OK');
return response; // 先返回占位符
}
return null;
})
.width('100%')
.height('100%')
}
}
}

三种方式对比

方式响应数据来源适用场景
同步字符串 内存中的字符串 动态生成的 HTML/JSON
同步 $rawfile 本地 rawfile 文件 替换线上资源为本地版本
异步 setResponseDataID 异步读取的任何来源 读大文件、调用异步 API
赞(0)
未经允许不得转载:171主机测评 » HarmonyOS ArkWeb 系列之自定义响应数据:onInterceptRequest 同步与异步两种方式
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址