HarmonyOS 鸿蒙Next:如何实现在web的onInterceptRequest回调方法里拦截h5页面的html,js,css和png等资源请求,然后从本地磁盘找到对应文件后转成WebResourceResponse对象后返回给Web,从而实现离线加载页面的功能
HarmonyOS 鸿蒙Next:如何实现在web的onInterceptRequest回调方法里拦截h5页面的html,js,css和png等资源请求,然后从本地磁盘找到对应文件后转成WebResourceResponse对象后返回给Web,从而实现离线加载页面的功能 我想在Web的onInterceptRequest回调方法里拦截h5页面的html,js,css和png等资源请求,然后从本地磁盘找到对应文件后转成WebResourceResponse对象后返回给Web,从而实现离线加载页面的功能。现在通过在线地址找手机本地磁盘离线资源的方法是Promise异步返回的,怎么做可以实现同步返回
可以先设置setResponseIsReady
为false
,那么内核此时不会去读取response的内容。当获取到fd后再将其改为true
,此时内核才会去读去响应数据。参考demo:
build() {
Column() {
Web({ src: $rawfile('catch.html'), controller: this.webviewController })
.onInterceptRequest((event) => {
if (event) {
console.log('url123456:' + event.request.getRequestUrl())
}
const url = event!.request.getRequestUrl();
if (!url.endsWith(".jpg")) {
return null;
}
try {
let url2 = 'https://img.tukuppt.com/photo-big/17/12/16/57/94/171216579483.jpg';
this.xxxx(url2).then(fd => {
this.responseweb.setResponseData(fd);
this.responseweb.setResponseCode(200);
this.responseweb.setReasonMessage('OK');
this.responseweb.setResponseIsReady(true);
console.log(fd + " 1234567")
});
this.responseweb.setResponseMimeType('image/*');
this.responseweb.setResponseIsReady(false);
console.log(this.responseweb.getResponseData().toString + "123456")
return this.responseweb;
} catch (error) {
console.error(`[Demo]Code: ${error.code},Message: ${error.message} `);
return null
}
})
}
}
参考文档如下: https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs-V5/faqs-arkweb-82-V5
setResponseIsReady
属性说明:
https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-web-V5#setresponseisready9
您可以看看该示例是否满足您的需求:
onInterceptRequest
接口,当Web组件加载url之前触发。返回值WebResourceResponse
。返回响应数据则按照响应数据加载,无响应数据则返回null
表示按照原来的方式加载。
// xxx.ets
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
responseWeb: WebResourceResponse = new WebResourceResponse();
heads: Header[] = new Array();
@State webData: string = "<!DOCTYPE html>\n<html>\n<head>\n<title>intercept test</title>\n</head>\n<body>\n<h1>intercept test</h1>\n</body>\n</html>";
build() {
Column() {
Web({ src: 'www.example.com', controller: this.controller })
.onInterceptRequest((event) => {
if (event) {
console.log('url:' + event.request.getRequestUrl());
}
let head1: Header = {
headerKey: "Connection",
headerValue: "keep-alive"
}
let head2: Header = {
headerKey: "Cache-Control",
headerValue: "no-cache"
}
let length = this.heads.push(head1);
length = this.heads.push(head2);
const promise: Promise<String> = new Promise((resolve: Function, reject: Function) => {
this.responseWeb.setResponseHeader(this.heads);
this.responseWeb.setResponseData(this.webData);
this.responseWeb.setResponseEncoding('utf-8');
this.responseWeb.setResponseMimeType('text/html');
this.responseWeb.setResponseCode(200);
this.responseWeb.setReasonMessage('OK');
resolve("success");
})
promise.then(() => {
console.log("prepare response ready");
this.responseWeb.setResponseIsReady(true);
})
this.responseWeb.setResponseIsReady(false);
return this.responseWeb;
})
}
}
}
请参考以下demo,在返回null
时,则添加如下代码this.responseResource.setResponseIsReady(false);
达到以下效果:返回响应数据则按照响应数据加载,无响应数据则返回null
表示按照原来的方式加载。
//rawfile/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<script src=""></script>
<body>
<!-- 页面资源请求 -->
<a href="https://www.example.com/test.html">intercept test111111!</a>
</body>
</html>
// xxx.ets
import web_webview from '@ohos.web.webview';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController()
responseResource: WebResourceResponse = new WebResourceResponse()
// 自定义响应数据
@State webData: string = '<!DOCTYPE html>\n<html>\n<head>\n<title>intercept test22222</title>\n</head>\n<body>\n<h1>intercept ok</h1>\n</body>\n</html>'
build() {
Column() {
Web({ src: $rawfile('index.html'), controller: this.controller })
.onInterceptRequest((event) => {
if (event) {
console.info('url:' + event.request.getRequestUrl());
// 拦截页面请求
if (event.request.getRequestUrl() !== 'https://www.example.com/test.html') {
console.log('拦截了')
return null;
}
}
try {
const promise: Promise<string> = new Promise((resolve: Function, reject: Function) => {
setTimeout(() => {
console.info('responseweb->setTimeout after wait');
// resolve('OK')
resolve(null)
}, 3000);
})
promise.then((result) => {
if(result==='OK'){
this.responseResource.setResponseData(this.webData);
this.responseResource.setResponseCode(200);
this.responseResource.setReasonMessage('OK');
this.responseResource.setResponseIsReady(true);
console.info('responseweb->set true');
}else{
this.responseResource.setResponseIsReady(false);//添加该逻辑
console.info('responseweb为null->set false');
}
}).catch((error: BusinessError) => {
console.error(error.message);
});
console.info('responseweb-> start setTimeout');
this.responseResource.setResponseMimeType('text/html');
this.responseResource.setResponseIsReady(false);
console.info('responseweb->set false');
return this.responseResource;
} catch (error) {
console.error('errorresponseweb->' + `${error.message}`);
return new WebResourceResponse();
}
})
}
}
}
更多关于HarmonyOS 鸿蒙Next:如何实现在web的onInterceptRequest回调方法里拦截h5页面的html,js,css和png等资源请求,然后从本地磁盘找到对应文件后转成WebResourceResponse对象后返回给Web,从而实现离线加载页面的功能的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙系统中,若想在onInterceptRequest
回调方法里拦截H5页面的HTML、JS、CSS和PNG等资源请求,并从本地磁盘找到对应文件后转成WebResourceResponse
对象返回给Web,可以按照以下步骤实现:
-
重写
shouldInterceptRequest
方法:在WebViewClient
的子类中重写此方法,用于拦截资源请求。 -
读取本地文件:根据请求的URL路径,从本地磁盘读取对应的HTML、JS、CSS或PNG文件。
-
构建
WebResourceResponse
:根据读取的文件内容及其MIME类型,构建WebResourceResponse
对象。 -
返回
WebResourceResponse
:将构建的WebResourceResponse
对象返回,以便WebView加载本地资源。
示例代码如下:
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
String url = request.getUrl().toString();
// 解析URL,获取资源路径
String filePath = getPathFromUrl(url);
if (filePath != null) {
try {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
String mimeType = getMimeType(filePath);
return new WebResourceResponse(mimeType, "UTF-8", fis);
} catch (Exception e) {
e.printStackTrace();
}
}
return super.shouldInterceptRequest(view, request);
}
// 根据文件扩展名获取MIME类型的方法需自行实现
private String getMimeType(String filePath) {
// 实现代码略
}
注意:上述代码示例中的getPathFromUrl
和getMimeType
方法需根据实际需求实现。
如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html