如何在WKWebView中本地加载iframe?附HTML页面实现需求
用WKWebView加载本地HTML及本地iframe的解决方案
嘿,我来帮你搞定这两个问题!下面分两部分详细说明:
一、加载本地HTML页面(含Bootstrap等资源)
首先要确保你的HTML文件、css/js等资源都正确添加到Xcode项目中,勾选「Copy items if needed」,同时在项目的「Build Phases」→「Copy Bundle Resources」里能看到这些文件。
1. 配置WKWebView权限
本地文件加载需要开启允许文件URL访问其他本地资源的权限,否则Bootstrap这类依赖外部文件的资源会加载失败,代码如下:
import WebKit // 创建WKWebView配置 let webViewConfig = WKWebViewConfiguration() // 关键:允许文件URL访问其他本地文件 webViewConfig.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") // 创建WKWebView并添加到视图 let webView = WKWebView(frame: view.bounds, configuration: webViewConfig) webView.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.addSubview(webView)
2. 加载本地HTML文件
假设你的主HTML文件名为AppendixB1.html,放在项目的WebContent子目录下(和css文件夹同级),用loadFileURL方法加载,同时设置允许访问的目录:
guard let htmlFileURL = Bundle.main.url( forResource: "AppendixB1", withExtension: "html", subdirectory: "WebContent" ) else { print("找不到本地HTML文件,请检查文件名和路径") return } // 允许访问HTML文件所在的整个目录,这样css/js等相对路径资源能正常加载 webView.loadFileURL(htmlFileURL, allowingReadAccessTo: htmlFileURL.deletingLastPathComponent())
注意:你HTML里的../../css/bootstrap.min.css路径要对应实际文件结构,比如如果HTML在WebContent/appendices下,css在WebContent/css,那相对路径应该是../css/bootstrap.min.css,确保路径正确才能加载到资源。
二、本地加载iframe的方法
加载本地iframe的核心还是确保权限开启,同时正确设置iframe的src路径:
1. 静态加载本地iframe内容
如果iframe的内容是另一个本地HTML文件,直接在主HTML里用相对路径设置src即可:
<!-- 假设主HTML在WebContent/appendices下,iframe的HTML在WebContent/iframes/iframe1.html --> <iframe src="../iframes/iframe1.html" width="100%" height="600" frameborder="0"></iframe>
只要之前开启了allowFileAccessFromFileURLs,这个iframe就能正常加载本地内容。
2. 动态加载本地iframe内容
如果需要通过代码动态设置iframe的本地内容,有两种方式:
方式一:修改iframe的src为本地文件URL
// 先获取iframe的本地文件URL guard let iframeURL = Bundle.main.url( forResource: "iframe1", withExtension: "html", subdirectory: "WebContent/iframes" ) else { return } // 把URL转为相对路径(相对于主HTML的目录),或者直接用fileURL的字符串 webView.evaluateJavaScript("document.getElementById('my-iframe').src = '\(iframeURL.absoluteString)'") { result, error in if let err = error { print("设置iframe失败:\(err.localizedDescription)") } }
方式二:直接加载HTML字符串到iframe
如果iframe的内容是动态生成的HTML字符串,可以结合baseURL来加载本地资源:
let iframeHTML = """ <!DOCTYPE html> <html> <head> <link href="../css/bootstrap.min.css" rel="stylesheet"> </head> <body> <h3>本地iframe内容</h3> </body> </html> """ // baseURL设为主HTML所在的目录,这样iframe里的相对路径资源能正常加载 guard let baseURL = Bundle.main.url(forResource: "AppendixB1", withExtension: "html", subdirectory: "WebContent/appendices")?.deletingLastPathComponent() else { return } webView.evaluateJavaScript(""" const iframe = document.getElementById('my-iframe'); const doc = iframe.contentDocument || iframe.contentWindow.document; doc.open(); doc.write(`\(iframeHTML)`); doc.close(); """)
关键注意事项
- 所有本地资源必须被正确添加到Bundle中,否则会找不到文件;
- 相对路径一定要对应实际的文件结构,避免路径错误;
allowFileAccessFromFileURLs是必须开启的,否则本地iframe和外部资源都会加载失败;- iOS 14及以上版本,不需要额外的隐私权限,只要配置正确就能正常加载。
内容的提问来源于stack exchange,提问作者dperazzolo




