HarmonyOS Next开发学习手册——拦截Web组件发起的网络请求

通过 网络拦截接口 对Web组件发出的请求进行拦截,并可以为被拦截的请求提供自定义的响应头以及响应体。

为Web组件设置网络拦截器

为指定的Web组件或者ServiceWorker设置ArkWeb_SchemeHandler,当Web内核发出相应scheme请求的时候,会触发ArkWeb_SchemeHandler的回调。需要在Web组件初始化之后设置网络拦截器。

当请求开始的时候会回调ArkWeb_OnRequestStart,请求结束的时候会回调ArkWeb_OnRequestStop。

如果想要拦截Web组件发出的第一个请求,可以通过 initializeWebEngine 对Web组件提前进行初始化,然后设置拦截器进行拦截。

  // 创建一个ArkWeb_SchemeHandler对象。
  ArkWeb_SchemeHandler *schemeHandler;
  OH_ArkWeb_CreateSchemeHandler(&schemeHandler);

  // 为ArkWeb_SchemeHandler设置ArkWeb_OnRequestStart与ArkWeb_OnRequestStop回调。
  OH_ArkWebSchemeHandler_SetOnRequestStart(schemeHandler, OnURLRequestStart);
  OH_ArkWebSchemeHandler_SetOnRequestStop(schemeHandler, OnURLRequestStop);

  // 拦截webTag为“scheme-handler”的Web组件发出的scheme为“https”的请求。
  OH_ArkWeb_SetSchemeHandler("https", "scheme-handler", schemeHandler);
  OH_ArkWebServiceWorker_SetSchemeHandler("https", schemeHandler);

也可以拦截非Web组件内置scheme的请求。

  // 创建一个ArkWeb_SchemeHandler对象。
  ArkWeb_SchemeHandler *schemeHandler;
  OH_ArkWeb_CreateSchemeHandler(&schemeHandler);

  // 为ArkWeb_SchemeHandler设置ArkWeb_OnRequestStart与ArkWeb_OnRequestStop回调。
  OH_ArkWebSchemeHandler_SetOnRequestStart(schemeHandler, OnURLRequestStart);
  OH_ArkWebSchemeHandler_SetOnRequestStop(schemeHandler, OnURLRequestStop);

  // 拦截webTag为“scheme-handler”的Web组件发出的scheme为“custom”的请求。
  OH_ArkWeb_SetSchemeHandler("custom", "scheme-handler", schemeHandler);
  OH_ArkWebServiceWorker_SetSchemeHandler("custom", schemeHandler);

设置自定义scheme需要遵循的规则

如果要拦截自定义scheme的请求,需要提前将自定义scheme注册到Web内核。需要在Web组件初始化之前进行注册,Web组件初始化后再注册会失败。

  // 注册“custom“ scheme到Web组件,并指定该scheme需要遵循标准的scheme规则,允许该scheme发出跨域请求。
  OH_ArkWeb_RegisterCustomSchemes("custom", ARKWEB_SCHEME_OPTION_STANDARD | ARKWEB_SCHEME_OPTION_CORS_ENABLED);
  // 注册“custom-local” scheme到Web组件,并指定该scheme需要遵循与“file” scheme一样的规则。
  OH_ArkWeb_RegisterCustomSchemes("custom-local", ARKWEB_SCHEME_OPTION_LOCAL);
  // 注册“custom-csp-bypassing”到Web组件,并指定该scheme需要遵循标准的scheme规则,允许忽略CSP检查。
  OH_ArkWeb_RegisterCustomSchemes("custom-csp-bypassing", ARKWEB_SCHEME_OPTION_CSP_BYPASSING | ARKWEB_SCHEME_OPTION_STANDARD);
  // 注册“custom-isolated”到Web组件,并指定该scheme的请求必须从相同scheme加载的网页中发起。
  OH_ArkWeb_RegisterCustomSchemes("custom-isolated", ARKWEB_SCHEME_OPTION_DISPLAY_ISOLATED);

由于注册scheme需要在Web组件初始化之前进行注册,而网络拦截器需要在Web组件初始化之后设置,建议在EntryAbility的onCreate中调用c++接口注册scheme。

scheme注册完毕后,通过 initializeWebEngine 对Web组件进行初始化,初始化完成后再设置网络拦截器。

  export default class EntryAbility extends UIAbility {
      onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
          // 注册scheme的配置。
          testNapi.registerCustomSchemes();
          // 初始化Web组件内核,该操作会初始化Browser进程以及创建BrowserContext。
          webview.WebviewController.initializeWebEngine();
          // 创建并设置ArkWeb_SchemeHandler。
          testNapi.setSchemeHandler();
      }
      ...
  };

获取被拦截请求的请求信息

通过OH_ArkWebResourceRequest_*接口获取被拦截请求的信息。可以获取url、method、referrer、headers、resourceType等信息。

  char* url;
  OH_ArkWebResourceRequest_GetUrl(resourceRequest_, &url);
  OH_ArkWeb_ReleaseString(url);

  char* method;
  OH_ArkWebResourceRequest_GetMethod(resourceRequest_, &method);
  OH_ArkWeb_ReleaseString(method);

  int32_t resourceType = OH_ArkWebResourceRequest_GetResourceType(resourceRequest_);

  char* frameUrl;
  OH_ArkWebResourceRequest_GetFrameUrl(resourceRequest_, &frameUrl);
  OH_ArkWeb_ReleaseString(frameUrl);
  ...

支持获取PUT/POST类请求的上传数据。数据类型支持BYTES、FILE、BLOB和CHUNKED。

  // 获取被拦截请求的上传数据。
  OH_ArkWebResourceRequest_GetHttpBodyStream(resourceRequest(), &stream_);
  // 设置读取上传数据的读回调。
  OH_ArkWebHttpBodyStream_SetReadCallback(stream_, ReadCallback);
  // 初始化ArkWeb_HttpBodyStream,其它OH_ArkWebHttpBodyStream*函数需要在初始化进行调用。
  OH_ArkWebHttpBodyStream_Init(stream_, InitCallback);

为被拦截的请求提供自定义的响应体

Web组件的网络拦截支持在worker线程以流的方式为被拦截的请求提供自定义的响应体。也可以以特定的 网络错误码 结束当前被拦截的请求。

  // 为被拦截的请求创建一个响应头。
  ArkWeb_Response *response;
  OH_ArkWeb_CreateResponse(&response);

  // 设置HTTP状态码为200。
  OH_ArkWebResponse_SetStatus(response, 200);
  // 设置响应体的编码格式。
  OH_ArkWebResponse_SetCharset(response, "UTF-8");
  // 设置响应体的大小。
  OH_ArkWebResponse_SetHeaderByName(response, "content-length", "1024", false);
  // 将为被拦截的请求创建的响应头传递给Web组件。
  OH_ArkWebResourceHandler_DidReceiveResponse(resourceHandler, response);

  // 该函数可以调用多次,数据可以分多份来传递给Web组件。
  OH_ArkWebResourceHandler_DidReceiveData(resourceHandler, buffer, bufLen);

  // 读取响应体结束,当然如果希望该请求失败的话也可以通过调用OH_ArkWebResourceHandler_DidFailWithError(resourceHandler_, errorCode);
  // 传递给Web组件一个错误码并结束该请求。
  OH_ArkWebResourceHandler_DidFinish(resourceHandler);

完整示例

使用DevEco Studio创建一个默认的Native C++工程,需要提前准备一个mp4文件,命名为test.mp4,将test.mp4放到main/resources/rawfile下。

main/ets/pages/index.ets

import testNapi from 'libentry.so';
import { webview } from '@kit.ArkWeb';
import { resourceManager } from '@kit.LocalizationKit';

@Entry
@Component
struct Index {
  mycontroller: web_webview.WebviewController = new web_webview.WebviewController("scheme-handler");

  build() {
    Row() {
      Column() {
        Button("goback").onClick( event => {
          this.mycontroller.backward();
        })

        Web({ src: $rawfile("test.html"), controller: this.mycontroller})
          .javaScriptAccess(true)
          .width('100%')
          .height('100%')
          .databaseAccess(true)
          .fileAccess(false)
          .domStorageAccess(true)
          .cacheMode(CacheMode.Default)
          .onPageBegin( event => {
            testNapi.initResourceManager(getContext().resourceManager);
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

main/ets/entryability/EntryAbility.ets

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import testNapi from 'libentry.so';
import { webview } from '@kit.ArkWeb';

export default class EntryAbility extends UIAbility {
    onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
        // 注册三方协议的配置。
        testNapi.registerCustomSchemes();
        // 初始化Web组件内核,该操作会初始化Browser进程以及创建BrowserContext。
        webview.WebviewController.initializeWebEngine();
        // 设置SchemeHandler。
        testNapi.setSchemeHandler();
    }

    onDestroy(): void {

    }

    onWindowStageCreate(windowStage: window.WindowStage): void {
        windowStage.loadContent('pages/Index', (err, data) => 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值