HarmonyOS鸿蒙Next中如何实现webview拦截所有网页中的请求,然后再原生应用端实现加解密?
HarmonyOS鸿蒙Next中如何实现webview拦截所有网页中的请求,然后再原生应用端实现加解密? 现在有一个需求,需要嵌入一个已有的现成网页,网页已经完成不能修改。
现在要拦截这个网页中所有请求,有些需要加密,有些不需要,在原生APP侧要进行对应的处理,该怎么做?请给我一个简单的demo,比如请求一个天气信息,显示出来,然后拦截了修改一下。里面还会遇到跨域的问题,搞了好久没搞出来……
最好不要直接贴文档,一个简单demo就行
楼主可以尝试使用setWebSchemeHandler来做处理:
为当前Web组件设置WebSchemeHandler, WebSchemeHandler类用于拦截指定scheme的请求。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
schemeHandler: webview.WebSchemeHandler = new webview.WebSchemeHandler();
build() {
Column() {
Button('setWebSchemeHandler')
.onClick(() => {
try {
this.controller.setWebSchemeHandler('http', this.schemeHandler);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
参考文档:Class (WebviewController)-@ohos.web.webview (Webview)-ArkTS API-ArkWeb(方舟Web)-应用框架 - 华为HarmonyOS开发者
更多关于HarmonyOS鸿蒙Next中如何实现webview拦截所有网页中的请求,然后再原生应用端实现加解密?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
Webview请求拦截及加解密处理示例:
// 使用ArkWeb最新Kits导入方式
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
// 存储自定义响应头
private headers: webview.Header[] = [
{ headerKey: "Access-Control-Allow-Origin", headerValue: "\*" },
{ headerKey: "Content-Type", headerValue: "application/json" }
];
build() {
Column() {
// 创建Webview组件
Web({ src: "https://your-page-url.com", controller: this.controller })
.onInterceptRequest((event) => {
// 拦截所有请求
const interceptedUrl = event.request.getRequestUrl();
// 判断需要加密的请求类型
if (interceptedUrl.includes('/weather')) {
// 构造加密响应
const encryptedData = this.encryptData({
temperature: "25℃",
weather: "Sunny"
});
// 返回自定义响应
return {
response: {
data: encryptedData,
headers: this.headers,
statusCode: 200
}
};
} else {
// 其他请求直接放行
return { response: null };
}
})
}
}
// 示例加密方法
private encryptData(data: object): string {
// 实际加解密逻辑需要根据业务实现
return JSON.stringify(data);
}
}
找HarmonyOS工作还需要会Flutter技术的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17
- Web组件加载URL时可以使用onLoadIntercept在加载URL之前触发回调,用于判断是否阻止此次的访问。
- onInterceptRequest也可以用于拦截URL并返回响应数据,onLoadIntercept返回true则直接拦截URL请求,onLoadIntercept返回false则走onInterceptReques的回调。
- onOverrideUrlLoading也可以进行拦截,在iframe加载HTTP(S)协议或about:blank时不会触发该回调,加载非HTTP(S)协议的跳转可以触发,调用loadUrl(String)主动触发的跳转不会触发该回调。
用schemeHandler或者onInterceptRequest拦截,如果加载的是本地的HTML页面,跨域
// 设置允许可以跨域访问的路径列表
this.controller.setPathAllowingUniversalAccess([
getContext().resourceDir,
getContext().filesDir + "/example",
])
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct PageWebIntercept {
// 创建Web控制器
controller: webview.WebviewController = new webview.WebviewController();
schemeHandler: webview.WebSchemeHandler = new webview.WebSchemeHandler();
build() {
Column() {
Web({
controller: this.controller,
src: 'https://developer.huawei.com/consumer/cn/doc/games-guides/games-quickgame-manifest-0000002351944509#section829569145720' // 需加载的网页地址
})
.javaScriptAccess(true)
.fileAccess(true)
.domStorageAccess(true)
.onlineImageAccess(true)
.onControllerAttached(() => {
console.info("onControllerAttached");
try{
this.schemeHandler.onRequestStart((request: webview.WebSchemeHandlerRequest,
resourceHandler: webview.WebResourceHandler) => {
console.info('schemeHandler:' + request.getRequestUrl());
if (request.getRequestUrl().endsWith("xxx")) {
// 获取请求头
let url = request.getRequestUrl();
// 获取请求头
let header = request.getHeader();
// 获取请求方法
let method = request.getRequestMethod();
// 获取请求体
let stream = request.getHttpBodyStream();
// 构造响应体返回
let response = new webview.WebSchemeHandlerResponse();
return true
}
return false
})
this.controller.setWebSchemeHandler('https', this.schemeHandler);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
.onInterceptRequest((event) => {
if (event) {
console.info('url:' + event.request.getRequestUrl());
// 拦截页面请求
if (event.request.getRequestUrl() == 'xxx') {
}
}
return null;
})
}
}
}
没满足要求,这个只能拦截地址栏的,不能拦截所有api请求的,
我需要拦截这个网页的请求,在原生应用端实现无感加解密,也就是说网页不需要改,想原生APP拿到请求之后操作,请问这个可以做吗?
在HarmonyOS Next中,使用WebviewController的onInterceptRequest方法拦截网页请求。通过注册拦截回调,获取请求URL及参数,传递至原生层进行加解密处理。处理完成后,使用WebviewController的proceed方法继续加载修改后的请求或响应数据。
在HarmonyOS Next中,可以通过WebviewController的onInterceptRequest
方法拦截所有网页请求,并在原生端处理加解密逻辑。以下是简单示例:
import webview from '@ohos.web.webview';
// 创建WebviewController实例
let webviewController: webview.WebviewController = webview.WebviewController.create();
// 设置请求拦截回调
webviewController.onInterceptRequest((request) => {
// 根据URL判断是否需要加密处理
if (request.url.includes('weather-api.com')) {
// 原生端加密逻辑(示例)
const encryptedData = nativeEncrypt(request.url);
// 返回自定义响应
return {
responseData: encryptedData,
responseMimeType: 'application/json',
responseEncoding: 'utf-8'
};
}
// 不需要处理的请求返回null
return null;
});
// 原生加密方法(需自行实现)
function nativeEncrypt(url: string): string {
// 这里实现你的加密逻辑,例如:
// 1. 发起原生网络请求
// 2. 对响应数据进行加密
// 3. 返回加密后的数据
return JSON.stringify({ encrypted: true, data: 'your_encrypted_data' });
}
// 加载网页
webviewController.loadUrl('https://your-webpage.com');
注意:
- 跨域问题需要在服务器端配置CORS,客户端无法直接绕过
- 加密逻辑需要根据具体需求在nativeEncrypt方法中实现
- 对于不需要拦截的请求返回null即可继续正常加载
这个示例展示了基本的请求拦截和响应修改流程,实际使用时需要根据具体加密需求完善nativeEncrypt方法的实现。