iOS WKWebView无法加载网页轮播图及搜索自动补全图片问题咨询
问题成因
- HTTPS混合内容拦截:iOS系统默认开启App Transport Security(ATS)限制,WKWebView默认禁止HTTPS页面加载HTTP协议的静态资源。很多站点的轮播图、搜索联想资源会存放在未升级HTTPS的旧图床中,普通浏览器对混合内容的限制等级更低,因此可以正常加载,而WKWebView会直接拦截这类请求。
- 请求身份校验不通过:站点的静态资源大多配置了CORS跨域校验、Referer校验规则,你当前使用的是WKWebView默认的User-Agent、Referer请求头,和普通浏览器的标识存在差异,会被资源服务器判定为非法请求直接拒绝,返回403状态码。
- 异步请求未携带会话Cookie:如果站点的图片资源需要登录态、会话Cookie才可访问,WKWebView默认不会在异步动态请求(轮播图懒加载、搜索联想异步请求)中携带跨域Cookie,导致资源请求被拦截。
- 懒加载逻辑不兼容:主流站点的图片大多使用懒加载方案,依赖Intersection Observer API判断元素是否在可视区域触发加载,你当前代码中WKWebView的加载时序和视图布局时序存在偏差,懒加载逻辑判断元素不可见,不会触发图片加载。
解决方法
1. 配置ATS规则放开Web内容加载限制
在项目的info.plist中添加如下配置,允许Web内容加载HTTP资源:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoadsInWebContent</key> <true/> </dict>
2. 调整WKWebView配置适配规则
修改WKWebView初始化逻辑,自定义UA、开启跨域访问权限、配置Cookie同步,完整修改后的代码如下:
import UIKit import WebKit // 全局复用WKProcessPool保证Cookie同步 private let sharedProcessPool = WKProcessPool() class ViewController: UIViewController, WKNavigationDelegate { let webView: WKWebView = { let prefs = WKWebpagePreferences() prefs.allowsContentJavaScript = true let configuration = WKWebViewConfiguration() configuration.processPool = sharedProcessPool configuration.defaultWebpagePreferences = prefs // 开启跨域文件访问权限 configuration.preferences.setValue(true, forKey: "allowUniversalAccessFromFileURLs") configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") let webView = WKWebView(frame: .zero, configuration: configuration) // 自定义UA和Safari保持一致,避免被资源拦截 webView.customUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15" return webView }() override func viewDidLoad() { super.viewDidLoad() view.addSubview(webView) webView.navigationDelegate = self guard let url = URL(string: "https://gopalmone.com") else{ return } // 配置请求携带Cookie var request = URLRequest(url: url) request.httpShouldHandleCookies = true webView.load(request) } // 页面加载完成后手动触发懒加载图片加载 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 执行JS触发所有懒加载图片加载 let lazyLoadJS = """ document.querySelectorAll('img[data-src], img[data-original]').forEach(img => { img.src = img.dataset.src || img.dataset.original; }); """ webView.evaluateJavaScript(lazyLoadJS) } // 处理资源请求校验,允许所有资源加载 func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { decisionHandler(.allow) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() webView.frame = view.bounds } }
内容的提问来源于stack exchange,提问作者Abhinav Banerjee
相关产品推荐
相关产品推荐

