HarmonyOS鸿蒙Next中setPathAllowingUniversalAccess跨域问题

HarmonyOS鸿蒙Next中setPathAllowingUniversalAccess跨域问题

let paramDir = url;
  let path = url.substring(7);
  let pathParts = path.split('/').filter(part => part.length > 0);
  if (pathParts.length >= 4) {
    let parentDirs = pathParts.slice(0, pathParts.length - 4);
    paramDir = "/" + parentDirs.join('/');
  }
  Log.i(TAG, "loadUrl paramDir = " + paramDir);
  webView.getController().setPathAllowingUniversalAccess([
    paramDir,
  ])
} catch (err) {
  Log.e(TAG, "setPathAllowingUniversalAccess err = " + err);
}
webView.getController().loadUrl(url, this.toWebHeaders(headers));

webview加载本地文件,配置过滤目录,能解决本地跨域问题,但是调用相机拍照的本地图片无法展示了,这样怎么处理?


更多关于HarmonyOS鸿蒙Next中setPathAllowingUniversalAccess跨域问题的实战教程也可以访问 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}`);
    }
  })

说明:使用setPathAllowingUniversalAccess需确保该路径可信任,并与用户文件隔离。

至于你说的调用相机之后的本地图片无法访问,应该是路径问题,建议将要显示的图片放在上面写的路径列表目录里。

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


HarmonyOS Next中setPathAllowingUniversalAccess接口用于设置文件路径的跨域访问权限。该接口允许应用访问指定路径下的文件,即使该路径位于应用沙箱之外。使用时需在module.json5配置文件中声明ohos.permission.FILE_ACCESS权限。调用该接口后,应用可获得对指定路径的读写能力。

在HarmonyOS Next中,setPathAllowingUniversalAccess 用于为Web组件设置允许跨域访问的本地文件路径,以解决本地文件加载时的跨域限制。根据您提供的代码和问题描述,分析如下:

1. 问题分析 您通过解析URL动态设置允许访问的目录(paramDir),这解决了部分本地文件的跨域加载问题。但调用相机拍摄的图片可能存储在应用沙箱的其他目录(如 media/ 或临时目录),这些路径未被包含在 setPathAllowingUniversalAccess 设置的路径中,导致图片因跨域限制无法在WebView中显示。

2. 解决方案 需要将相机图片的存储路径也添加到允许跨域访问的路径列表中。具体方法取决于图片的存储位置:

  • 如果图片存储在应用沙箱内(如通过 context.filesDircontext.cacheDir 获取的路径),可以将这些目录路径加入列表:

    let allowedPaths = [paramDir];
    // 添加应用文件目录
    let filesDir = context.filesDir;
    allowedPaths.push(filesDir);
    
    // 添加缓存目录(如果图片存在这里)
    let cacheDir = context.cacheDir;
    allowedPaths.push(cacheDir);
    
    webView.getController().setPathAllowingUniversalAccess(allowedPaths);
    
  • 如果使用媒体库保存图片,需要获取图片的实际路径并确保其所在目录已被允许。例如,如果图片保存在 internal://app/media/ 目录下:

    allowedPaths.push("internal://app/media/");
    
  • 通用方案:如果无法确定具体目录,可以临时允许整个沙箱根目录(谨慎使用,仅建议调试):

    allowedPaths.push("internal://app/");
    

    但正式发布时应限制为必要的最小路径范围。

3. 注意事项

  • 路径需使用HarmonyOS文件管理规范格式(如 internal://app/...)。
  • 确保路径字符串以目录分隔符结尾(如 "internal://app/media/"),以明确表示目录。
  • 跨域设置仅适用于本地文件(file://internal:// 协议),不适用于网络资源。

通过将相机图片的存储目录添加到允许列表中,即可解决图片因跨域策略无法显示的问题。

回到顶部