【关键字】
Web组件 / onInterceptRequest / 异步 / HTTP请求 / setResponseIsReady
【问题描述】
Web组件的onInterceptRequest是同步方法,需要在此方法中执行HTTP请求,如何获取异步返回HTTP请求的返回结果?能否同步获取HTTP结果?
【解决方案】
系统HTTP请求只有异步方式,没有同步方式,可以用setResponseIsReady控制response异步返回。
在网络请求前设置为false,此时Web组件内核不会去读取reponse的内容。请求完成后设置为true,Web内核才会去响应数据。
前端页面index.html代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<!-- 页面资源请求 -->
<a href="https://www.example.com/test.html">intercept test!</a>
</body>
</html>
应用侧代码:
// xxx.ets
import web_webview from '@ohos.web.webview';
@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 test</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') {
return null;
}
}
try {
//模拟异步请求
new Promise((resolve)=>{
setTimeout(() => {
console.info('responseweb->setTimeout after wait');
resolve('OK')
}, 3000);
}).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');
}
});
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('responseweb->' + `${error.message}`);
return new WebResourceResponse();
}
})
}
}
}