鸿蒙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 安全策略的无尽骚扰。

相关推荐
特立独行的猫a5 小时前
鸿蒙 PC 命令行工具迁移实战 · 内部课件(详细配套版)
华为·harmonyos·移植·鸿蒙pc
廖松洋(Alina)6 小时前
04极速划词页面实现-鸿蒙PC端Electron开发
华为·electron·开源·harmonyos·鸿蒙
轻口味6 小时前
HarmonyOS 6.1 全栈实战录 - 07 极速连接:Remote Communication Kit (RCP) 实战与认证挑战深度解析
华为·harmonyos
想你依然心痛6 小时前
HarmonyOS 6(API 23)实战:基于悬浮导航、沉浸光感与Face AR & Body AR的“灵犀康养“——PC端沉浸式AR智能康复训练系统
华为·ar·harmonyos·悬浮导航·沉浸光感
廖松洋(Alina)6 小时前
03主入口页面与导航结构-鸿蒙PC端Electron开发
前端·javascript·华为·electron·开源·harmonyos·鸿蒙
廖松洋(Alina)6 小时前
09词根分解与水印展示-鸿蒙PC端Electron开发
前端·javascript·华为·electron·开源·harmonyos·鸿蒙
音视频牛哥6 小时前
大牛直播SDK(SmartMediaKit)鸿蒙NEXT同屏RTMP推流与轻量级RTSP服务集成实践指南
华为·harmonyos·大牛直播sdk·鸿蒙next无纸化同屏·鸿蒙next rtmp推流·鸿蒙next rtsp服务器·鸿蒙next无纸化会议
xmdy58666 小时前
Flutter + 开源鸿蒙实战|城市智慧停车管理系统 Day4 停车订单生成+多状态管理+在线缴费+我的订单+会员中心+个人中心完善
flutter·开源·harmonyos
xmdy58667 小时前
Flutter + 开源鸿蒙实战|城市智慧停车管理系统 Day8 进阶美化与真机调优篇
flutter·华为·harmonyos
Swift社区7 小时前
鸿蒙 PC vs Web:谁才是未来应用形态?
前端·华为·harmonyos