HarmonyOS鸿蒙Next中如何解决Web组件发送跨域Ajax请求时服务端校验失败的问题

HarmonyOS鸿蒙Next中如何解决Web组件发送跨域Ajax请求时服务端校验失败的问题

【问题现象】

Web组件发送跨域Ajax请求时无法携带cookie,导致服务端校验无法通过。

点击放大

【背景知识】

  • 企业小程序实现常见思路是基于H5的方案

企业应用内基于H5技术实现企业内部小程序的一种常见思路是通过Web组件加载H5页面。由于其中涉及加载本地或三方的html,因此需要云侧视情况放通跨域。

若云侧接口需登陆才能调用,通常会把鉴权标记以cookie的形式放在http header中。

出于安全考虑,此种情况下,通常服务端会额外对referer和origin进行校验。

  • cookie中的samesite和secure字段的作用

cookieManager是浏览器内核中存储和cookie的模块。发送跨域ajax请求成功的前提是:

  1. cookieManager中存储有对应目标域名的cookie
    • 在Web开发场景,一般通过响应头里set-cookie实现,HarmonyOSwebview的场景通过configCookieSync方法实现。
  2. 目标域名允许跨域携带cookie
    • HarmonyOSwebview支持目标站点的cookie设置为samesite=none;secure的模式下,ajax请求携带跨域cookie;
    • samesite=none;secure限制场景是https。

【定位思路】

在使用Web组件直接加载沙箱文件,出于消减cookie泄露的风险,HarmonyOSWeb组件通过file协议加载沙箱的html时,html内发出的Ajax请求不支持携带跨域的cookie。

【解决方案】

方案总体示意如下:

点击放大

第1步:通过configCookieSync接口把cookie设置到cookieManager中

configCookieSync接口提供了操作webview的cookieManager的能力。

文档:文档中心 (huawei.com)

核心代码如下:

Web({ src: 'http://example.com/a.html', controller: this.controller })
.onControllerAttached(()=>{
  // 给www.huawei.com指定了baidu=111111的cookie
  webview.WebCookieManager.configCookieSync('https://www.huawei.com', 'baidu=111111; SameSite=none; Secure');
})

注意

  1. 云侧需为https协议接口,不支持http;
  2. cookie需设置SameSite=none; Secure。

第2步:通过onInterceptRequest拦截并替换静态html

核心代码如下,即在onInterceptRequest中拦截html文件流的请求,并将之替换为沙箱文件的文件描述符:

Web({ src: 'http://example.com/a.html', controller: this.controller })
.onInterceptRequest((event) => {
  if (!event) {
    return;
  }
  // 此处匹配自己想要加载的本地离线资源,进行资源拦截替换,绕过跨域
  if (this.schemeMap.has(event.request.getRequestUrl())) {
    let rawfileName: string = this.schemeMap.get(event.request.getRequestUrl())!;
    let mimeType = this.mimeTypeMap.get(rawfileName);
    if (typeof mimeType === 'string') {
      let response = new WebResourceResponse();
      // 构造响应数据,如果本地文件在rawfile下,可以通过如下方式设置
      response.setResponseData($rawfile(rawfileName));
      response.setResponseEncoding('utf-8');
      response.setResponseMimeType(mimeType);
      response.setResponseCode(200);
      response.setReasonMessage('OK');
      response.setResponseIsReady(true);
      return response;
    }
  }
  return null;
})

第3步:通过Devtools远程调试Web组件,观察结果

通过Devtools远程调试Web组件方法见指导:远程调试

可通过Devtools观察结果:

点击放大

【总结】

通过Web组件加载H5,并在其中发送跨域请求是企业开发和企业内部小程序框架的常见场景,涉及携带cookie的场景可参考该方案实现。


更多关于HarmonyOS鸿蒙Next中如何解决Web组件发送跨域Ajax请求时服务端校验失败的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中如何解决Web组件发送跨域Ajax请求时服务端校验失败的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,解决Web组件发送跨域Ajax请求时服务端校验失败的问题

可以按照以下步骤操作:

  1. 使用configCookieSync接口将cookie设置到cookieManager中,确保cookie包含SameSite=none; Secure,且云侧接口为https协议。

  2. 通过onInterceptRequest拦截并替换静态html,将请求的html文件流替换为沙箱文件的文件描述符,绕过跨域限制。

  3. 使用Devtools远程调试Web组件,观察请求结果,确保跨域请求成功携带cookie。

通过以上步骤,可以解决Web组件发送跨域Ajax请求时服务端校验失败的问题。

回到顶部