如何防止WKWebView拖放操作暴露App容器URL?
iOS WKWebView拖放非法链接暴露容器路径的解决方法
在iOS中,当包含非法href值(如<a href="{SomeDynamicFieldTobeResolvedLaterAsLink}">Link</a>)的链接被拖放到添加了UIDropInteraction的WKWebView时,应用的容器文件路径会被泄露,示例路径如下:
file:///Users/username/Library/Developer/CoreSimulator/Devices/A26FB816-FBA1-427D-BC8C-8F425C296676/data/Containers/Bundle/Application/59625BC8-A075-465F-802D-9F0C77D75488/
该问题在真机环境中同样存在,以下是几种可行的解决思路:
方法一:拦截修改拖放的NSItemProvider数据
在UIDropInteraction的代理方法中,拦截拖放内容,检查并清理掉包含容器路径的链接数据:
func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) { session.loadObjects(ofClass: NSString.self) { items in for item in items { guard let linkString = item as? String else { continue } // 匹配容器路径特征并替换为空 let containerPathPattern = "file:///.*?/Containers/Bundle/Application/" if let regex = try? NSRegularExpression(pattern: containerPathPattern, options: .caseInsensitive) { let cleanedLink = regex.stringByReplacingMatches( in: linkString, options: [], range: NSRange(location: 0, length: linkString.count), withTemplate: "" ) // 使用清理后的链接进行后续拖放处理 } } } }
方法二:预处理页面中的非法链接
通过WKUserScript提前修改页面内的非法href链接,替换为合法占位值,避免拖放时触发容器路径生成:
let fixInvalidLinksScript = """ document.querySelectorAll('a[href^="{"]').forEach(link => { // 替换为无操作的合法href link.href = 'javascript:void(0)'; // 保留原动态值到自定义属性,后续需要时可读取 link.dataset.originalHref = link.getAttribute('href'); }); """ let userScript = WKUserScript( source: fixInvalidLinksScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true ) webView.configuration.userContentController.addUserScript(userScript)
方法三:禁用特定拖放行为
如果不需要支持链接拖放,可以在拖放交互的代理方法中直接拒绝相关请求:
func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool { // 拒绝包含URL或字符串类型的拖放请求,避免链接拖放 return !session.canLoadObjects(ofClass: URL.self) && !session.canLoadObjects(ofClass: NSString.self) }
也可以更精准地检测拖放内容是否为非法链接,再决定是否允许。
方法四:拦截拖放触发的导航请求
通过WKNavigationDelegate拦截拖放引发的导航请求,阻止包含容器路径的请求:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if navigationAction.navigationType == .other { guard let url = navigationAction.request.url else { decisionHandler(.allow) return } // 检测URL是否包含容器路径特征 if url.absoluteString.range(of: "file:///.*?/Containers/Bundle/Application/", options: .regularExpression) != nil { decisionHandler(.cancel) // 可在此添加自定义提示,告知用户链接无效 } else { decisionHandler(.allow) } } else { decisionHandler(.allow) } }
内容的提问来源于stack exchange,提问作者Kris2k
相关产品推荐
相关产品推荐

