iOS SwiftUI中WKWebView加载Microsoft Bookings页面异常求助
问题描述
在iOS SwiftUI应用中使用WKWebView加载Microsoft Bookings网页(已测试多个公开预订页面,均出现此问题)。该功能此前正常运行,但现在Microsoft Bookings会显示通用错误“Something went wrong”的错误页面,附带刷新按钮(点击后跳转登录页面)。但在Android WebView或常规浏览器中,这些页面均可正常访问。
另外,在WVNavigationDelegate中还注入了一段JS脚本以拦截特定调用、检测预订完成状态,但为简化说明已省略,且该问题在无此代码时仍会出现。
相关代码
import SwiftUI import WebKit struct WebView: UIViewRepresentable { let request: URLRequest let options: Options private var navDelegate: WKNavigationDelegate private var scrollDelegate: UIScrollViewDelegate init( request: URLRequest, options: Options = Options() ) { self.request = request self.content = nil // 注:原代码未定义content变量,此处保留原代码内容 self.options = options self.navDelegate = WVNavigationDelegate() self.scrollDelegate = WVUIScrollViewDelegate(scrollEnabled: options.scrollEnabled) } func makeUIView(context: Context) -> WKWebView { let wv = WKWebView() wv.navigationDelegate = navDelegate wv.scrollView.delegate = scrollDelegate // 此设置未起到预期作用 if #available(iOS 15.4, *) { wv.configuration.preferences.isSiteSpecificQuirksModeEnabled = true } return wv } func updateUIView(_ uiView: WKWebView, context: Context) { uiView.load(request) // 注:原代码中req应为request,此处修正笔误 uiView.scrollView.isScrollEnabled = options.scrollEnabled } struct Options { var scrollEnabled: Bool = true var zoomEnabled: Bool = true } } class WVUIScrollViewDelegate: NSObject, UIScrollViewDelegate { let scrollEnabled: Bool init(scrollEnabled: Bool) { self.scrollEnabled = scrollEnabled } func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) { scrollView.pinchGestureRecognizer?.isEnabled = scrollEnabled } } class WVNavigationDelegate: NSObject, WKNavigationDelegate { // 尝试解决Cookie问题,但无效果 func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { guard let response = navigationResponse.response as? HTTPURLResponse, let url = navigationResponse.response.url else { decisionHandler(.cancel) return } if let headerFields = response.allHeaderFields as? [String: String] { let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url) cookies.forEach { cookie in webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie) HTTPCookieStorage.shared.setCookie(cookie) } } decisionHandler(.allow) } }
解决建议
除Cookie外,可从以下几个方向排查并调整配置:
配置User-Agent:Microsoft服务可能对WKWebView的默认UA做了限制,尝试模拟Safari移动端的User-Agent:
func makeUIView(context: Context) -> WKWebView { let config = WKWebViewConfiguration() // 替换为对应iOS版本的Safari UA let safariUA = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1" config.applicationNameForUserAgent = safariUA let wv = WKWebView(frame: .zero, configuration: config) wv.navigationDelegate = navDelegate wv.scrollView.delegate = scrollDelegate if #available(iOS 15.4, *) { wv.configuration.preferences.isSiteSpecificQuirksModeEnabled = true } return wv }确保JavaScript与Web API支持:Bookings页面可能依赖JavaScript或特定Web API,需开启相关配置:
// 在WKWebViewConfiguration中添加 config.preferences.javaScriptEnabled = true config.preferences.javaScriptCanOpenWindowsAutomatically = true // 若页面需要存储数据,确保允许 config.websiteDataStore = WKWebsiteDataStore.default()检查App Transport Security (ATS) 设置:在
Info.plist中配置允许Microsoft相关域名的HTTPS请求,若存在混合内容需添加例外:<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <false/> <key>NSExceptionDomains</key> <dict> <key>microsoft.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSAllowsArbitraryLoads</key> <true/> </dict> </dict> </dict>优化WebView加载逻辑:
- 避免重复加载:
updateUIView中每次调用都会触发加载,添加URL判断防止重复请求:func updateUIView(_ uiView: WKWebView, context: Context) { guard uiView.url != request.url else { return } uiView.load(request) uiView.scrollView.isScrollEnabled = options.scrollEnabled } - 移除自定义ScrollView代理:自定义的
WVUIScrollViewDelegate可能干扰页面默认交互,尝试直接通过wv.scrollView.isScrollEnabled控制滚动,无需设置代理。
- 避免重复加载:
添加必要请求头部:为URLRequest补充
Accept-Language、Referer等头部,匹配浏览器请求格式:var request = URLRequest(url: yourBookingsUrl) request.setValue("en-US,en;q=0.9", forHTTPHeaderField: "Accept-Language") request.setValue(yourBookingsUrl.absoluteString, forHTTPHeaderField: "Referer")清除WebView缓存:旧缓存可能导致加载异常,初始化WebView前清除网站数据:
WKWebsiteDataStore.default().removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), modifiedSince: Date.distantPast) { // 缓存清除后再初始化并加载WebView }
内容的提问来源于stack exchange,提问作者Vama
相关产品推荐
相关产品推荐

