You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中WKWebView无法通过JS fetch加载本地文件的解决需求

解决WKWebView中本地HTML fetch相对路径文件的问题

问题情况

将本地HTML文件加载到SwiftUI的WKWebView中时,HTML内的fetch("/somefolder/model.txt")无法识别应用的完整文件路径,导致请求失败。但手动构造完整URL在Safari移动端浏览器中可正常访问该文件。

问题原因

  1. 访问权限范围限制:当前代码中loadFileURL的allowingReadAccessTo参数设置为index.html文件的URL,这意味着WebView仅能访问该文件所在的目录,无法访问其他目录下的文件。
  2. 重复加载请求冲突:updateUIView中同时调用了loadFileURL和load(request),这会导致WebView加载逻辑混乱,优先使用普通的load(request)而不是带访问权限的loadFileURL。
  3. 相对路径不匹配:HTML中使用的根路径/somefolder不符合bundle内的文件结构,bundle中的文件路径是相对根目录的,而非系统根路径。

解决方案

1. 调整WKWebView的加载逻辑和访问权限

修改updateUIView方法,将allowingReadAccessTo设置为bundle的根目录,同时移除重复的load(request)调用:

struct SwiftUIWebview: UIViewRepresentable{
    func makeUIView(context: Context) -> WKWebView {
        let prefs = WKWebpagePreferences()
        prefs.allowsContentJavaScript = true
        let config = WKWebViewConfiguration()
        config.defaultWebpagePreferences = prefs
        config.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
        let browser = WKWebView(frame: .zero, configuration: config)
        return browser
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        guard let indexURL = Bundle.main.url(forResource: "index", withExtension: "html"),
              let bundleRoot = Bundle.main.resourceURL else { return }
        
        // 仅使用loadFileURL,设置访问权限为bundle根目录
        uiView.loadFileURL(indexURL, allowingReadAccessTo: bundleRoot)
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            SwiftUIWebview()
        }
    }
}

2. 修正HTML中的相对路径

根据bundle内的实际文件结构调整fetch的路径:

  • 如果somefolder和index.html在同一层级,使用相对路径:
<script>
    // 相对路径,从index.html所在目录出发
    const url = "./somefolder/model.txt"
    fetch(url)
       .then(r => r.text())
       .then(t => console.log(t))
</script>
  • 如果somefolder是bundle根目录下的子目录,也可以使用绝对路径(基于bundle根目录):
<script>
    // 基于bundle根的绝对路径
    const url = "somefolder/model.txt"
    fetch(url)
       .then(r => r.text())
       .then(t => console.log(t))
</script>

3. 验证文件的Bundle配置

确保model.txt和somefolder已正确添加到Xcode项目中,并且在Target Membership中勾选了对应的应用目标,保证文件被打包到bundle内。

内容的提问来源于stack exchange,提问作者Sayan Pandey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:35:17