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

相关推荐
SummerKaze16 小时前
为鸿蒙开发者写一个 nvm:hmvm 的设计与实现
harmonyos
在人间耕耘2 天前
HarmonyOS Vision Kit 视觉AI实战:把官方 Demo 改造成一套能长期复用的组件库
人工智能·深度学习·harmonyos
王码码20352 天前
Flutter for OpenHarmony:socket_io_client 实时通信的事实标准(Node.js 后端的最佳拍档) 深度解析与鸿蒙适配指南
android·flutter·ui·华为·node.js·harmonyos
HarmonyOS_SDK2 天前
【FAQ】HarmonyOS SDK 闭源开放能力 — Ads Kit
harmonyos
Swift社区3 天前
如何利用 ArkUI 框架优化鸿蒙应用的渲染性能
华为·harmonyos
特立独行的猫a3 天前
uni-app x跨平台开发实战:开发鸿蒙HarmonyOS影视票房榜组件完整实现过程
华为·uni-app·harmonyos·轮播图·uniapp-x
盐焗西兰花3 天前
鸿蒙学习实战之路-STG系列(5/11)-守护策略管理-添加与修改策略
服务器·学习·harmonyos
盐焗西兰花3 天前
鸿蒙学习实战之路-STG系列(4/11)-应用选择页功能详解
服务器·学习·harmonyos
lbb 小魔仙3 天前
鸿蒙跨平台项目实战篇03:React Native Bundle增量更新详解
react native·react.js·harmonyos
特立独行的猫a3 天前
uni-app x跨平台开发实战:开发鸿蒙HarmonyOS滚动卡片组件,scroll-view无法滚动踩坑全记录
华为·uni-app·harmonyos·uniapp-x