HarmonyOS 鸿蒙Next Web组件跨域问题

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS 鸿蒙Next Web组件跨域问题 使用web组件加载本地html时,html中的fetch方法存在跨域有问题,但是XMLHttpRequest是不存在跨域问题的。

示例代码
1、html代码

// Make a GET request using fetch
const url = "http://192.168.21.30:8000/getName";

function withFetch() {
  fetch(url)
    .then(response => response.json())
    .then(data => {
      // Handle the response data
      console.log(data);
      document.getElementById("txt").innerHTML =
        data.name + " with Fetch";
    })
    .catch(error => {
      // Handle any errors
      console.error(error);
    });
}

function withXhr() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.send();
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
      console.log(xhr.responseText);
      document.getElementById("txt").innerHTML =
        xhr.responseText + " with XHR";
    }
  };
}

function crossFetch() {
  const url = "http://192.168.21.30:8000/getName2";
  fetch(url)
    .then(response => response.json())
    .then(data => {
      // Handle the response data
      console.log(data);
      document.getElementById("txt").innerHTML =
        data.name + " cross with Fetch";
    })
    .catch(error => {
      // Handle any errors
      console.error(error);
      document.getElementById("txt").innerHTML =
        error.message + " cross with Fetch";
    });
}

function crossXhr() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.send();
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
      console.log(xhr.responseText);
      document.getElementById("txt").innerHTML =
        xhr.responseText + " cross with XHR";
    }
  };
}

2、服务器端代码:

const http = require('http');

const server = http.createServer((req, res) => {
  if (req.url === '/getName') {
    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Access-Control-Allow-Origin', '*'); // Allow all origins
    res.setHeader('Access-Control-Allow-Methods', 'GET'); // Allow only GET method
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); // Allow only Content-Type header
    res.end(JSON.stringify({ name: 'Moses' }));
  } else if (req.url === '/getName2') {
    res.end(JSON.stringify({ name: 'Moses2' }));
  } else {
    res.statusCode = 404;
    res.end('Not Found');
  }
});

const port = 9000;
server.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

ArkTs代码:

import web_webview from '@ohos.web.webview';

@Entry
@Component
struct WebComponent {
  webviewController: web_webview.WebviewController = new web_webview.WebviewController();

  build() {
    Column() {
      Button('loadUrl')
        .onClick(() => {
          try {
            // 点击按钮时,通过loadUrl,跳转到www.example1.com
            this.webviewController.loadUrl($rawfile('index.html'));
          } catch (error) {
            console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
          }
        })
      // 组件创建时,加载www.example.com
      Web({ src: 'https://baidu.com', controller: this.webviewController })
        .onErrorReceive(e => {
          console.log(e?.error.getErrorInfo())
        })
        .width("100%")
        .height("100%")
        .onPageEnd(e => {
          console.log("[moses]end:" + e?.url)
        })
        .onPageBegin(e => {
          console.log("[moses]begin:" + e?.url)
        })
        .onProgressChange(e => {
          console.log("[moses] onProgressChange:" + e?.newProgress)
        })// .constraintSize({ minHeight: 1 })
          // .backgroundColor(Color.Transparent)
        .javaScriptAccess(true)
        .horizontalScrollBarAccess(true)
        .verticalScrollBarAccess(true)
        .overviewModeAccess(true)// .textZoomRatio(1)
        .domStorageAccess(true)
        .imageAccess(true)
        .geolocationAccess(true)
        .onlineImageAccess(true)
        .databaseAccess(true)
        .zoomAccess(true)
        .onGeolocationShow(e => {
          console.log("[moses] onGeolocationShow:" + e?.origin)
        })

    }
  }
}

希望Fetch作为本地加载也能跨域


更多关于HarmonyOS 鸿蒙Next Web组件跨域问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

示例代码

.onControllerAttached(() => {
  try {
    // 设置允许可以跨域访问的路径列表
    this.myController.getWebViewController().setPathAllowingUniversalAccess([
      getContext().resourceDir,
    ])
    this.myController.getWebViewController().loadUrl(`resource://resfile/index.html?#${this.params}`)
  } catch (error) {
    console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
  }
})

onControllerAttached文档:ArkWeb_ComponentAPI-结构体-模块-C API-ArkWeb(方舟Web)-应用框架 - 华为HarmonyOS开发者 (huawei.com)

setPathAllowingUniversalAccess文档:@ohos.web.webview (Webview)-ArkTS API-ArkWeb(方舟Web)-应用框架 - 华为HarmonyOS开发者 (huawei.com)

更多关于HarmonyOS 鸿蒙Next Web组件跨域问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


这种情况只能解决本地资源跨域,不能解决 axios 请求跨域。

升级HarmonyOS后,发现手机的游戏性能也有了显著提升。

大佬,axios跨域请求问题解决了吗?

大佬,axios跨域请求问题解决了吗?

可以使用customizeSchemes接口来自定义协议解决跨域问题和fetch请求,参考连接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-webview-V5#customizeschemes

有 demo 吗?

针对HarmonyOS鸿蒙Next Web组件的跨域问题,以下是专业且直接的回答:

HarmonyOS鸿蒙Next Web组件在处理跨域请求时,主要依赖于其内置的Web引擎对CORS(跨来源资源共享)策略的支持。跨域问题通常发生在Web应用尝试从不同源(域、协议或端口)的服务器请求资源时,如果服务器未正确配置CORS响应头,浏览器将阻止这些请求以保护用户安全。

解决鸿蒙Next Web组件跨域问题的关键在于服务器端配置。确保目标服务器在响应中包含适当的CORS头,如Access-Control-Allow-Origin,以允许来自特定源或所有源的请求。此外,还可以配置其他CORS头来细化控制,如Access-Control-Allow-Methods(允许的HTTP方法)和Access-Control-Allow-Headers(允许的HTTP头)。

如果服务器已正确配置CORS,但问题依旧存在,可能是鸿蒙Next Web组件的Web引擎对CORS的实现有特定要求或限制。此时,建议检查鸿蒙官方文档或更新至最新版本,以确认是否存在已知问题或改进。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部