You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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加载逻辑:

    1. 避免重复加载:updateUIView中每次调用都会触发加载,添加URL判断防止重复请求:
      func updateUIView(_ uiView: WKWebView, context: Context) {
          guard uiView.url != request.url else { return }
          uiView.load(request)
          uiView.scrollView.isScrollEnabled = options.scrollEnabled
      }
      
    2. 移除自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 19:50:25