【HarmonyOS】Web组件使用setResponseIsReady+setResponseData实现异步自定义响应数据

发布时间 2023-12-12 10:33:00作者: Mayism123

【问题描述】

在web组件的自定义响应数据方法如下:

Web().onInterceptRequest((event) => {
…
})

如果需要在callbak中如果使用Promise等获取异步信息,并读取该如何操作

 

【解决方案】

通过setResponseIsReady + setResponseData的方式控制数据返回,先设置setResponseIsReady为false,此时Web内核不会去读取response的内容。当获取到数据后再将其改为true后,Web内核才会去响应数据,参考以下demo: 

前端页面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();
          }
        })
    }
  }
}