鸿蒙Cordova开发踩坑记录:跨域请求的“隐形墙“

摘要 :在开发调试阶段,我们经常遇到一个诡异现象:在浏览器里运行正常的 AJAX 请求,一放到鸿蒙真机上就报错 Network ErrorCORS error。这通常是因为混合应用运行在 file://resource:// 协议下,被浏览器的同源策略(Same-Origin Policy)无情拦截。本文讲解如何配置 ArkWeb 的跨域白名单。

🚧 1. 隐形的高墙

当前端页面位于 index.html (本地文件) 时,它的 Origin 是 file://null

当它尝试请求后端接口 https://api.game-server.com/score 时,这就构成了一个跨域请求

现代 WebView 的安全策略越来越严:

  1. 禁止 file:// 访问 http/https(Mixed Content)。
  2. 禁止 file:// 发送 AJAX 到任何域(除非服务器显式允许 Access-Control-Allow-Origin: *)。
  3. Preflight (OPTIONS) 请求失败。

🛠️ 2. 爆破方案

我们不需要后端配合改 Header(因为有时候调的是第三方 API),我们可以从客户端侧**"解除封印"**。

2.1 方案一:Web组件配置 (ArkTS)

ArkWeb 提供了若干个开关,用于放宽安全限制。

typescript 复制代码
Web({ src: this.url, controller: this.controller })
  .domStorageAccess(true)
  .fileAccess(true)
  .imageAccess(true)
  // 关键:允许混合内容(https 页面加载 http 资源)
  .mixedMode(MixedMode.All) 
  // 关键:允许 file 协议下的跨域访问
  .fileAccess(true) 
  .javaScriptAccess(true)

注意:仅靠这些配置,在某些高版本 Android/鸿蒙内核上,CORS 依然会被拦截。

2.2 方案二:代理转发 (Interceptor) ✅

这是最稳妥的方案。既然 Webview 限制跨域,那我们就让 Native 代码去发请求。Native 的 HTTP 请求(http.createHttp())是不受同源策略限制的。

原理

Web -> 拦截特定 URL -> Native HTTP -> Server -> Native -> Web

我们复用第 8 篇中的 onInterceptRequest 机制:

typescript 复制代码
// GamePlugin.ets

// 拦截 /api/ 前缀的请求
if (url.includes('/api/')) {
    // 使用鸿蒙原生网络库发送请求
    let httpRequest = http.createHttp();
    let response = await httpRequest.request(realApiUrl, {
        method: 'POST',
        header: { 'Content-Type': 'application/json' },
        extraData: requestBody
    });
    
    // 构造 Web 响应,并手动添加 CORS 头
    let webResponse = new WebResourceResponse();
    webResponse.setResponseHeader([
        { headerKey: "Access-Control-Allow-Origin", headerValue: "*" } // 强行允许
    ]);
    webResponse.setResponseData(response.result);
    return webResponse;
}

2.3 方案三:Cordova HTTP 插件

如果你不想自己写拦截器,可以直接使用社区成熟的插件 cordova-plugin-advanced-http

它会在 JS 层替换标准的 fetchXMLHttpRequest,底层通过 Native 代码发送请求。

优点

  • 自动处理 SSL Pinning。
  • 无视 CORS。
  • 支持 Cookie 管理。

Web 端代码

javascript 复制代码
cordova.plugin.http.post('https://api.example.com/data', {
    id: 123
}, {
    Authorization: 'Bearer token'
}, function(response) {
    console.log(response.status);
}, function(response) {
    console.error(response.error);
});

🕸️ 3. UserAgent 伪装

有时候请求被拒不是因为跨域,而是因为服务器把来自 WebView 的请求当成了爬虫或非法客户端。

我们可以修改 UA 来伪装身份。

typescript 复制代码
Web({ ... })
  .userAgent("Mozilla/5.0 (Phone; HarmonyOS; GameApp/1.0) AppleWebKit/537.36")

这对于请求一些对 UA 敏感的 CDN 资源(如防盗链图片)非常有用。

📚 4. 总结

面对跨域墙:

  1. 初级 :配置 mixedModefileAccess(仅对部分旧内核有效)。
  2. 中级:后端开启 CORS(需要控制权)。
  3. 高级Native 代理转发。这是终极解决方案,它不仅解决了 CORS,还能解决 SSL 证书校验、自定义 DNS 解析等高级网络需求。

在混合开发中,把网络层下沉到 Native,虽然麻烦一点,但能避开 Web 安全策略的无尽骚扰。

相关推荐
Z***25806 小时前
HarmonyOS在物联网场景的应用
物联网·华为·harmonyos
Pocker_Spades_A8 小时前
John the Ripper 在 HarmonyOS 上的构建与适配
华为·harmonyos
不爱吃糖的程序媛9 小时前
鸿蒙PC Electron 打印服务实现详解
华为·electron·harmonyos
开源头条12 小时前
2025开源鸿蒙开发者激励计划正式启动,为生态繁荣注入持久动力
华为·开源·harmonyos
奔跑的露西ly15 小时前
【HarmonyOS NEXT】自定义样式复用
华为·harmonyos
lqj_本人15 小时前
HarmonyOS + Cordova:打包发布与环境差异常见问题指南
华为·harmonyos
不羁的木木15 小时前
【开源鸿蒙跨平台开发学习笔记】Day03:React Native 开发 HarmonyOS-GitCode口袋工具开发-1
笔记·学习·harmonyos
lqj_本人15 小时前
鸿蒙Cordova开发踩坑记录:震动反馈的“时差“
华为·harmonyos
lqj_本人17 小时前
鸿蒙原生与Qt混合开发:性能优化与资源管理
qt·harmonyos