大家好,我是[晚风依旧似温柔],新人一枚,欢迎大家关注~

前言

在应用里临时打开登录页、活动页、第三方服务页时,有一类需求很明确:页面在当前会话里可以正常使用 Cookie 和缓存,但用户退出后,不希望这些浏览数据继续留在本地。

如果自己在普通 Web 组件上做清理,需要同时考虑 Cookie、缓存、Web 存储以及网页侧权限状态,生命周期一复杂就容易漏项。ArkWeb 提供的 incognitoMode 更适合这种“临时 Web 会话”——官方明确说明,隐私模式浏览时 Cookie、缓存等数据不会写入本地持久化存储,并会在对应 Web 组件销毁后清除。

本文就聚焦一个具体场景:在 HarmonyOS 7 应用中打开一个临时 Web 页面,让 Cookie 只服务于当前隐私会话,并把组件销毁作为会话结束边界。

一、普通 Web 真正需要担心的,不只是 Cookie

讨论隐私模式之前,先把一个容易混淆的地方说清楚:普通模式并不意味着“所有数据一定永久留下”,而是它不具备隐私模式提供的“不写入本地持久化存储 + Web 组件销毁后清除”这一组保证。

一个网页在运行过程中,可能涉及 Cookie、网络缓存、Web 数据存储,以及网站对应的地理位置权限状态。ArkWeb 官方隐私模式文档也分别提供了 Cookie、WebStorage、GeolocationPermissions 等针对隐私数据空间的管理方式。

所以,如果业务真正想表达的是:

“这个网页只允许在当前打开期间保留会话状态,退出之后不要把浏览状态带到下一次。”

比起在普通 Web 上逐项补清理逻辑,直接建立一个独立的隐私 Web 会话更贴合需求。

典型业务包括一次性认证页、临时第三方服务页、访客浏览、公共设备上的 Web 页面,以及应用内部提供的“无痕浏览”入口。

二、先确认版本:HarmonyOS 7 对应 API 26.0.0

华为当前的升级适配文档明确说明,HarmonyOS 7.0 对应 API 版本为 26.0.0,并建议升级到对应开发套件进行适配。

这里有一个版本概念不要混淆:ArkWeb 隐私模式不是 HarmonyOS 7 才新增的能力。 WebOptions 中的 incognitoMode 属于较早已经提供的 ArkWeb 能力;隐私模式相关接口中,地理位置管理接口的 incognito 参数官方 API 参考明确标记为 API version 11+。在 HarmonyOS 7 / API 26.0.0 环境下,可以继续使用这套能力。

本文采用的核心模块是:

import { webview } from '@kit.ArkWeb';

也就是 ArkWeb Kit 提供的 Web 控制能力。核心组件仍然是 ArkUI 的 Web,控制器使用 webview.WebviewController。

如果加载在线网页,还需要声明网络访问权限。华为 ArkWeb 官方 FAQ 明确指出,Web 页面涉及网络资源获取时,需要在 module.json5 中配置 ohos.permission.INTERNET。

{
  "module": {
    // ...
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]
  }
}

三、最小实践:建立一个临时隐私 Web 会话

这个示例只验证三件事:

  1. Web 组件以隐私模式创建;
  2. Cookie 写入、读取都明确操作隐私模式的数据空间;
  3. Web 组件销毁后,让 ArkWeb 按隐私模式规则完成会话数据清理。

真正开启隐私模式的代码其实只有一个参数:

Web({
  src: 'https://www.example.com',
  controller: this.controller,
  incognitoMode: true
})

华为官方给出的隐私模式示例也是在创建 Web 时将 incognitoMode 设置为 true。官方同时明确说明:隐私浏览产生的 Cookie、缓存等不会写入本地持久化存储,隐私模式 Web 组件销毁后,这些数据会被清除。

这句话非常关键。

隐私模式并不是“禁用 Cookie”。

网页在当前隐私会话里仍然可以使用 Cookie。区别在于这些 Cookie 属于隐私模式的数据空间,不应把“无痕”理解成“网页完全没有状态”。

四、用 Cookie 把行为观察得更直观

下面代码按照华为官方隐私模式文档中的 configCookieSync、fetchCookieSync 和 clearAllCookiesSync 接口组织成一个最小观察示例。这里不声称代码已经在具体工程中编译运行,实际发布前仍应使用目标 SDK 和设备完成验证。

import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct PrivateWebPage {
  private controller: webview.WebviewController =
    new webview.WebviewController();

  private readonly url: string = 'https://www.example.com';

  build() {
    Column() {
      Button('写入隐私 Cookie')
        .onClick(() => {
          try {
            webview.WebCookieManager.configCookieSync(
              this.url,
              'a=b',
              true
            );
          } catch (error) {
            console.error(
              `configCookie failed: ${(error as BusinessError).code}, ` +
              `${(error as BusinessError).message}`
            );
          }
        })

      Button('读取隐私 Cookie')
        .onClick(() => {
          try {
            const value =
              webview.WebCookieManager.fetchCookieSync(
                this.url,
                true
              );
            console.info(`private cookie: ${value}`);
          } catch (error) {
            console.error(
              `fetchCookie failed: ${(error as BusinessError).code}, ` +
              `${(error as BusinessError).message}`
            );
          }
        })

      Button('立即清空隐私 Cookie')
        .onClick(() => {
          webview.WebCookieManager.clearAllCookiesSync(true);
        })

      Web({
        src: this.url,
        controller: this.controller,
        incognitoMode: true
      })
        .width('100%')
        .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
  }
}

真正需要关注的是这些 API 最后的布尔参数。

官方文档中,configCookieSync(..., true) 的 true 表示操作隐私模式对应的 Cookie;fetchCookieSync(..., true) 获取隐私 WebView 的内存 Cookie;clearAllCookiesSync(true) 清除的同样是隐私模式 Cookie。

也就是说,不能只把 Web 创建成隐私模式,然后在应用侧管理 Cookie 时又忘记指定隐私数据空间。

五、Cache 的关键不是“不缓存”,而是“不持久化”

这里比较容易理解错。

incognitoMode: true 并不等价于“所有网络资源每次都必须重新下载”,也不要把它理解成简单的“关闭缓存开关”。

官方给出的定义是:隐私模式下 Cookie、缓存等数据不会写入本地持久化存储;隐私模式 Web 组件销毁后,这些数据会被清除。

因此,从业务设计角度更准确的说法应该是:

隐私模式允许 Web 在当前会话中正常工作,但不把这类浏览数据作为跨会话的本地持久状态留下。

这也是它和“每次退出页面以后手工调用若干清缓存 API”最大的区别:隐私属性从 Web 创建时就确定了,而不是等退出时再补救。

如果业务还使用了 Web SQL,官方隐私模式示例提供了:

webview.WebStorage.deleteAllData(true);

其中 true 表示删除隐私模式下内存中的 Web 数据。官方示例将其与隐私 Web 组件和 databaseAccess(true) 配合使用。

需要注意,不能因为官方这里演示了 Web SQL,就自行扩展成“所有浏览器存储类型都应该手工调用这个接口删除”。对于官方没有明确给出对应关系的存储类型,文章和业务代码都应该按实际 API 文档逐项确认。

六、地理位置授权也有“普通”和“隐私”两个空间

隐私 WebView 如果会打开地图、门店查询、附近服务等 H5 页面,还要考虑地理位置。

GeolocationPermissions 提供了针对 Web 组件网站来源的地理位置权限管理。当前官方 API 参考中,allowGeolocation 的定义为:

static allowGeolocation(
  origin: string,
  incognito?: boolean
): void

其中 incognito 从 API version 11 开始支持;传入 true 表示允许隐私模式下指定来源使用地理位置。

例如:

webview.GeolocationPermissions.allowGeolocation(
  'https://www.example.com',
  true
);

如果需要撤销这个隐私会话中的来源授权,则可以使用:

webview.GeolocationPermissions.deleteGeolocation(
  'https://www.example.com',
  true
);

或者清理隐私模式下所有来源的地理位置权限状态:

webview.GeolocationPermissions.deleteAllGeolocation(true);

这里还有两个约束很容易漏掉。

一是 origin 必须符合 RFC 6454 定义的来源格式;二是官方 API 参考说明,目前调用 GeolocationPermissions 下的方法,需要先加载 Web 组件。

另外,网页来源授权不能替代 HarmonyOS 应用本身的位置权限。 如果页面确实需要访问设备位置,还要按照 Location Kit 的位置权限规则处理应用侧授权。官方当前的位置权限指导区分了模糊位置、精准位置和后台位置场景:前台精准位置需要结合 ohos.permission.APPROXIMATELY_LOCATION 与 ohos.permission.LOCATION;后台定位则有额外要求。

所以,不使用定位的临时 Web 页面没必要为了“示例完整”多申请位置权限。

七、退出页面和销毁 Web 组件不是同一回事

这是整套实践里最需要留意的生命周期问题。

官方对隐私数据自动清理给出的边界是:

“隐私模式的 Web 组件销毁后”。

因此,业务代码不要把“用户已经看不到这个页面”直接等同于“Web 已经销毁”。

例如在带页面栈、Tabs 或组件缓存的结构里,一个页面可能只是进入非激活状态。华为关于 ArkUI 组件冻结的官方资料就明确展示了 Navigation 中非栈顶 NavDestination 可以处于 inactive 状态,返回时再次恢复 active;这和页面节点已经销毁不是一个概念。

因此,如果产品定义的是严格的“关闭隐私会话”,页面架构也应该保证对应 Web 组件最终真正结束生命周期,而不是长期把它隐藏在导航栈或缓存节点中。

如果业务要求用户点击“清除浏览数据”后立即清理,而不是等待组件销毁,则可以主动调用隐私模式对应的清理接口,例如:

webview.WebCookieManager.clearAllCookiesSync(true);
webview.WebStorage.deleteAllData(true);
webview.GeolocationPermissions.deleteAllGeolocation(true);

这些接口分别针对 Cookie、Web 数据存储以及地理位置权限状态,不能把其中某一个当成“万能清除 Web 全部数据”的 API。

八、普通模式与隐私模式怎么选

对比项普通 Web隐私 Web
创建方式默认模式incognitoMode: true
Cookie使用普通模式 Cookie 数据空间使用隐私模式 Cookie 数据空间
Cookie 持久化不具备隐私模式“不写持久化”的保证官方明确不写入本地持久化存储
Cache普通缓存行为不写入本地持久化存储,组件销毁后清理
地理位置来源授权incognito 默认 false管理接口传入 true
WebStorage 管理普通数据空间可通过带 true 参数的隐私模式接口操作
会话结束需要根据业务决定数据清理策略Web 组件销毁是官方定义的数据清理边界

这张表背后的选择其实很简单:需要长期登录、保留站点状态、下次进入继续使用的业务,通常应该使用普通 Web;一次性授权、访客模式、临时第三方页面、公共设备浏览或者明确要求“退出即结束会话”的页面,更适合隐私 Web。

九、实际项目中建议这样排查

如果隐私页面出现“重新进入后还像是登录状态没有退出”的情况,不要第一反应就认定 incognitoMode 无效,可以按下面顺序检查:

  1. 确认创建参数:目标 Web 是否真的设置了 incognitoMode: true。
  2. 确认 Cookie 数据空间:应用主动读写 Cookie 时,是否也操作了隐私模式,而不是默认普通模式。
  3. 确认组件生命周期:退出页面以后 Web 是真正销毁,还是只变成不可见或 inactive。
  4. 确认状态来源:所谓“登录状态”是否真的来自 Cookie,而不是应用自己的 ArkTS 状态、服务端账号状态或其他业务数据。
  5. 确认地理位置等权限状态:涉及 Web 来源权限时,是否使用了对应的 incognito: true。
  6. 确认网络权限:在线网页加载异常时,检查 module.json5 中的 ohos.permission.INTERNET。
  7. 确认 SDK 版本:HarmonyOS 7 项目应结合 API 26.0.0 开发套件和 API 变更信息完成兼容性验证。

开发经验总结

ArkWeb 隐私模式本身并不复杂,真正有价值的是把它理解成一种会话级的数据隔离机制,而不是一个简单的“清 Cookie 开关”。

开发时可以记住四件事:incognitoMode: true 在创建 Web 时确定隐私属性;Cookie、WebStorage、地理位置权限都有对应的隐私模式数据空间;隐私模式不是禁止 Cookie 和缓存,而是不把这些浏览数据写入本地持久化存储;官方自动清理规则的生命周期边界是 Web 组件销毁。

对于 HarmonyOS 7 项目,还要把“系统版本”和“接口首次支持版本”分开理解。HarmonyOS 7.0 对应 API 26.0.0,但 ArkWeb 隐私浏览能力并不是这一版本才出现。升级到新 SDK 后,仍然应该逐项核对当前 API 参考,而不是把旧文章中的接口签名直接搬进项目。

如果正在设计一个“退出即不保留浏览痕迹”的 Web 页面,最值得检查的往往不是有没有在退出按钮里多写几个 clear,而是:这个页面从创建开始是不是就在隐私数据空间里,以及退出之后那个 Web 组件到底有没有真正结束生命周期。

如果觉得有帮助,别忘了点个赞+关注支持一下~
喜欢记得关注,别让好内容被埋没~

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐