iOS Swift 4:WKWebView/UIWebView无法加载HTML字符串中的图片
解决WKWebView/UIWebView加载HTML字符串时图片无法显示的问题
我来帮你搞定这个问题!你遇到的核心原因是:API返回的HTML里,图片并没有用<img>标签直接嵌入,而是放在了带colorbox类的<a>标签的href属性里——WKWebView和UIWebView默认只会把这当成普通链接,不会自动解析成图片显示。
因为你没办法修改API返回的HTML内容,所以我们可以通过注入自定义JavaScript脚本,在网页加载完成后自动把符合条件的<a>标签转换成<img>标签,让图片直接显示出来。
方案一:WKWebView实现(Swift 4)
我们可以在WKWebView的配置中添加用户脚本,让它在文档加载完成后自动执行转换逻辑:
import WebKit class YourViewController: UIViewController, WKNavigationDelegate { private var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() // 1. 创建WKWebView配置 let webConfig = WKWebViewConfiguration() // 2. 编写转换图片的JS脚本 let imageConversionScript = """ // 筛选所有带colorbox类且包含图片属性的a标签 const colorboxImageLinks = document.querySelectorAll('a.colorbox[data-cbox-img-attrs]'); colorboxImageLinks.forEach(link => { // 验证链接是否为图片格式(可根据需求扩展后缀) const validImgExts = ['.jpg', '.jpeg', '.png', '.gif', '.webp']; const linkHref = link.href.toLowerCase(); const isImage = validImgExts.some(ext => linkHref.endsWith(ext)); if (isImage) { // 创建img元素 const img = document.createElement('img'); img.src = link.href; img.title = link.title || ''; // 设置图片自适应样式,避免超出屏幕 img.style.maxWidth = '100%'; img.style.height = 'auto'; // 用img标签替换原a标签 link.parentNode.replaceChild(img, link); } }); """ // 3. 将脚本添加到配置中,在文档加载完成后执行 let userScript = WKUserScript( source: imageConversionScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true ) webConfig.userContentController.addUserScript(userScript) // 4. 创建并加载WKWebView webView = WKWebView(frame: view.bounds, configuration: webConfig) webView.navigationDelegate = self view.addSubview(webView) // 5. 加载API返回的HTML字符串 let apiHtmlString = "<h2>This is a heading</h2> <a href=\"https://www.w3schools.com/w3css/img_lights.jpg\" title=\"\" class=\"colorbox\" data-colorbox-gallery=\"gallery-paragraphs_item-7725-ZrzXIAds_FA\" data-cbox-img-attrs=\"\"></a>" webView.loadHTMLString(apiHtmlString, baseURL: nil) } }
方案二:UIWebView实现(Swift 4)
如果还在使用UIWebView,可以在网页加载完成后手动执行JS脚本:
import UIKit class YourViewController: UIViewController, UIWebViewDelegate { private var webView: UIWebView! override func viewDidLoad() { super.viewDidLoad() // 1. 创建并配置UIWebView webView = UIWebView(frame: view.bounds) webView.delegate = self view.addSubview(webView) // 2. 加载API返回的HTML字符串 let apiHtmlString = "<h2>This is a heading</h2> <a href=\"https://www.w3schools.com/w3css/img_lights.jpg\" title=\"\" class=\"colorbox\" data-colorbox-gallery=\"gallery-paragraphs_item-7725-ZrzXIAds_FA\" data-cbox-img-attrs=\"\"></a>" webView.loadHTMLString(apiHtmlString, baseURL: nil) } // 网页加载完成后执行转换脚本 func webViewDidFinishLoad(_ webView: UIWebView) { let imageConversionScript = """ const colorboxImageLinks = document.querySelectorAll('a.colorbox[data-cbox-img-attrs]'); colorboxImageLinks.forEach(link => { const validImgExts = ['.jpg', '.jpeg', '.png', '.gif', '.webp']; const linkHref = link.href.toLowerCase(); const isImage = validImgExts.some(ext => linkHref.endsWith(ext)); if (isImage) { const img = document.createElement('img'); img.src = link.href; img.title = link.title || ''; img.style.maxWidth = '100%'; img.style.height = 'auto'; link.parentNode.replaceChild(img, link); } }); """ _ = webView.stringByEvaluatingJavaScript(from: imageConversionScript) } }
注意事项
- 我在JS脚本里特意加了
[data-cbox-img-attrs]的筛选条件,这样只会转换那些明确是图片预览的colorbox链接,避免误转换其他同类型的a标签。 - 如果你的API返回的图片后缀不在脚本列表里,可以自行扩展
validImgExts数组。 - 要确保图片的URL是公开可访问的,没有跨域或者权限限制,否则WebView还是无法加载。
内容的提问来源于stack exchange,提问作者shadowpath
相关产品推荐
相关产品推荐

