HarmonyOS鸿蒙Next中ArkWeb加载html文件,文件中用到了ajax请求相对路径的html文件问题

HarmonyOS鸿蒙Next中ArkWeb加载html文件,文件中用到了ajax请求相对路径的html文件问题

function () {
    $.ajax({
        type : 'GET',
        url : url, // 整个项目用的相对路径,example '../demo.html'
        success : function(response) {
            console.log("$.ajax-success" + url);
            $("#rightForm").html(response);
            $("#rightjs").html('<script src="' + js + '" />');
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log("$.ajax-error" + JSON.stringify(jqXHR))
            console.log("$.ajax-error" + JSON.stringify(textStatus))
            console.log("$.ajax-error" + JSON.stringify(errorThrown))
        }
    });
}

ajax报错 {“readyState”:0,“responseText”:"",“status”:0,“statusText”:“error”}

尝试了

.javaScriptAccess(true)
.databaseAccess(true)
.mixedMode(MixedMode.All)
.zoomAccess(false)
.fileAccess(true)
.domStorageAccess(true)
.onInterceptRequest((event) => {
  let requestUrl = event.request.getRequestUrl()
  if (requestUrl.includes('.html')) {
    logUtil.hilogE('onInterceptRequest requestUrl:' + requestUrl)
  }
  return null
})

在onInterceptRequest 都没有看见ajax请求的拦截


更多关于HarmonyOS鸿蒙Next中ArkWeb加载html文件,文件中用到了ajax请求相对路径的html文件问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

本地资源跨域

场景描述

在Web开发与调试工作中,经常会出现通过本地文件系统直接打开HTML页面,并访问同目录下的本地脚本、样式或图片等资源的情况。这时,浏览器会因为协议不同而判定为跨域,从而触发安全限制,导致资源加载失败。

本地资源跨域具体的安全限制表现如下:

  • AJAX(XMLHttpRequest/Fetch):无法向另一个本地文件发送请求,会遇到经典的CORS(跨域资源共享)错误。
  • 访问iframe内容:如果一个file://协议页面通过<iframe>嵌入另一个本地文件,父页面无法使用JavaScript读取或操作iframe内部的内容。
  • Web Workers:可能无法从本地文件启动。
  • 某些HTML5 API:如localStorage和sessionStorage的访问可能会受到更严格的限制,甚至在某些情况下不可用。
  • CSS和JavaScript模块:使用import、@import<link rel="modulepreload">引用其他本地模块文件时,可能会失败。

本节以“WebView 加载本地H5离线包(file://协议),且该离线H5发起HTTP请求”的场景举例,介绍file协议下不同源跨域问题的解决方案。

实现原理

通过setPathAllowingUniversalAccess()设置一个路径列表。当使用file协议访问该列表中的资源时,允许进行跨域访问本地文件。此外,一旦设置了路径列表,file协议将仅限于访问列表内的资源(此时,fileAccess的行为将会被此接口行为覆盖)。

开发步骤

setPathAllowingUniversalAccess()设置的路径列表中的路径应符合以下任一路径格式:

  1. 应用文件目录通过Context.filesDir()获取,其子目录示例如下:
    • /data/storage/el2/base/files/example
    • /data/storage/el2/base/haps/entry/files/example
  2. 应用资源目录通过Context.resourceDir()获取,其子目录示例如下:
    • /data/storage/el1/bundle/entry/resource/resfile
    • /data/storage/el1/bundle/entry/resource/resfile/example

当路径列表中的任一路径不满足上述条件时,系统将抛出异常码401,并判定路径列表设置失败。如果路径列表设置为空,file协议的可访问范围将遵循fileAccess规则。

在当前示例中,本地H5页面存放在工程的resfile目录下,通过setPathAllowingUniversalAccess()设置resfile目录,将本地H5及其引用资源文件都放在允许跨域访问的路径列表中,解决页面发起http请求跨域问题。

Web({ src: 'resource://resfile/LocalResource/dist/index.html', controller: this.controller })
  .onControllerAttached(() => {
    try {
      // Set the list of paths that allow cross-origin access
      this.controller.setPathAllowingUniversalAccess([
        this.uiContext.getHostContext()!.resourceDir + '/LocalResource',
      ])
    } catch (error) {
      Logger.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
    }
  })

其它跨域情况详见开发文档:https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-cross-domain-solutions-for-web-pages

更多关于HarmonyOS鸿蒙Next中ArkWeb加载html文件,文件中用到了ajax请求相对路径的html文件问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,ArkWeb加载本地HTML文件时,ajax请求相对路径的HTML文件可能因安全策略或路径解析问题导致失败。需确保文件位于应用沙箱目录内,并使用正确的资源访问方式。可通过resourceManager.getRawFile获取文件路径,或使用ArkWeb提供的loadUrl方法加载本地资源。注意检查文件权限和路径配置。

在HarmonyOS Next的ArkWeb中,使用Ajax请求相对路径的本地HTML文件失败,核心原因是ArkWeb默认的安全策略限制了file://协议下的跨域请求

你遇到的 status:0readyState:0 错误是典型的跨域请求被浏览器(或WebView)安全策略阻止的标志。虽然你已正确配置了.fileAccess(true),但这仅允许Web组件访问设备文件,并未解决Ajax请求的安全限制。

根本原因与解决方案:

  1. 协议与同源策略:当主HTML文件通过file://协议加载时,Ajax请求的'../demo.html'同样会被视为file://协议下的请求。在WebView的安全模型中,file://协议下的Ajax请求通常受到严格限制,极易触发同源策略违规。

  2. 推荐解决方案:使用拦截器重写请求。 这是处理此问题最直接有效的方法。你需要在onInterceptRequest回调中,将Ajax请求的相对路径URL转换为ArkWeb可以加载的正确资源路径。

    webviewController.onInterceptRequest((event) => {
      let requestUrl = event.request.getRequestUrl();
      // 判断是否为需要处理的本地HTML文件请求
      if (requestUrl.endsWith('.html')) {
        // 示例:将相对路径转换为应用内的资源路径
        // 假设你的HTML文件存放在应用的`rawfile`目录下
        let newUrl = requestUrl.replace('file://', 'resource://rawfile/');
        // 或者,如果文件在特定目录下,可以构建具体路径
        // let newUrl = 'resource://rawfile/你的目录/' + getFileNameFromUrl(requestUrl);
        
        event.request.setRequestUrl(newUrl);
        logUtil.hilogE('Intercepted and rewritten URL: ' + newUrl);
      }
      // 注意:此处应返回event.request,而不是null
      return event.request;
    })
    

    关键点

    • file://协议转换为HarmonyOS应用资源协议,如resource://rawfile/
    • 确保目标HTML文件已放置在项目的rawfile目录(或你指定的资源目录)中。
    • 在回调结束时返回event.request对象,而不是null,以便使用修改后的请求继续加载。
  3. 检查配置:确保你的ArkWeb配置允许加载本地资源,你已配置的项是必要的,但需配合拦截器使用:

    .fileAccess(true)
    .domStorageAccess(true)
    .javaScriptAccess(true)
    

为何你的onInterceptRequest未拦截到请求: 可能是因为拦截条件不匹配或回调返回null过早终止了处理。确保在回调中正确判断URL并返回修改后的请求对象。

总结:问题根源在于file://协议下的Ajax跨域限制。通过onInterceptRequest拦截请求,将相对路径转换为应用资源路径(如resource://rawfile/),是ArkWeb中加载本地HTML资源的可靠方法。请根据你的项目文件结构,调整URL重写的逻辑。

回到顶部