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
本地资源跨域
在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()设置的路径列表中的路径应符合以下任一路径格式:
- 应用文件目录通过Context.filesDir()获取,其子目录示例如下:
- /data/storage/el2/base/files/example
- /data/storage/el2/base/haps/entry/files/example
- 应用资源目录通过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.filesDir或context.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://协议),不适用于网络资源。
通过将相机图片的存储目录添加到允许列表中,即可解决图片因跨域策略无法显示的问题。

