HarmonyOS 网络请求跨域(CORS)报错排查与解决

前言

“端上 http.request 报跨域"是社区高频误会:很多同学把浏览器同源策略套到 ArkTS 原生网络栈上,折腾半天加错地方。本文厘清"到底谁在报跨域”,并给出分场景的可运行解法。

问题描述

  • ArkTS 原生 http.request 直接报"跨域";
  • Web 组件里运行的 H5 fetch 被拦,报 CORS;
  • 服务端是别人的,无法改响应头,H5 请求死活不通。

细节解析

关键点:ArkTS 原生的 @ohos.net.http 模块不做 CORS 校验——它是系统网络栈,不像浏览器有同源策略。"原生请求报跨域"几乎都是误判或混淆:

  • A. 原生请求报"网络错误"(不是跨域):查 INTERNET 权限、HTTPS 配置、URL 拼错;
  • B. Web 内 H5 跨域:浏览器内核确实校验 CORS,需要在网页服务器加响应头;
  • C. Web 与原生同源通信:用 javaScriptProxy / runJavaScript 让 H5 调原生转发,绕开浏览器跨域。

服务端是你自己的,最干净的做法是直接加 CORS 头;第三方不支持 CORS 的,用原生层做代理转发。

示例代码

A. 原生请求(不校验 CORS,注意权限)

// 别忘了 module.json5 里声明 "ohos.permission.INTERNET"
import http from '@ohos.net.http';

async function getJson(url: string): Promise<string> {
  const req = http.createHttp();
  try {
    const resp = await req.request(url, { method: http.RequestMethod.GET });
    // 原生网络栈不做 CORS 校验,报的是网络/HTTP 错误而非"跨域"
    return resp.result as string;
  } finally {
    req.destroy();
  }
}

B. Web 内 H5 跨域:服务端加响应头

Access-Control-Allow-Origin: https://your.harmony.app
Access-Control-Allow-Methods: GET,POST,OPTIONS
Access-Control-Allow-Headers: Content-Type,Authorization

C. 用原生桥接让 H5 绕开跨域

// 原生侧注入桥对象,H5 通过 window.nativeBridge.get() 调原生转发
import { webview } from '@kit.ArkWeb';

class ApiBridge {
  get(url: string): string {
    // 在这里用原生 http 请求(无 CORS 限制),再把结果回传 H5
    return 'result-from-native';
  }
}

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

  build() {
    Web({ src: 'https://your.harmony.app', controller: this.controller })
      .javaScriptProxy({
        object: new ApiBridge(),
        name: 'nativeBridge',
        methodList: ['get'],
      })
  }
}
// H5 侧
const data = window.nativeBridge.get('/api/foo');  // 经原生转发,不受浏览器跨域限制

总结

  • 原生 http 不校验 CORS,所谓"原生跨域"通常是权限/HTTPS/URL 问题;
  • H5 在 Web 里才受 CORS 约束,解法是服务端加 CORS 头;
  • 第三方无 CORS 时,用 javaScriptProxy 让原生转发最稳;
  • 排查顺序:先确认是 A/B/C 哪一类,再对症下药,别乱加头。
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐