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

SwiftUI中WKWebView加载CloudFlare验证HTML显示白屏求助

iOS WKWebView加载Cloudflare验证HTML白屏问题排查

我们的链接采用CloudFlare防护,触发验证请求后后端返回HTML代码,使用WKWebView加载时iOS设备仅显示白屏。已尝试将加载逻辑从makeUIView移至updateUIView,修改了Info.plist中AllowArbitraryLoadsForWebView相关设置,均无效果。相同HTML代码在Android端可正常加载,且该HTML包含需执行的脚本,已配置相关JavaScript权限。

因隐私政策无法提供完整HTML代码,但该代码在在线工具中可正常运行。测试加载简单HTML(如<html><body><h1>Hello, World!</h1></body></html>)可正常显示。目前代理类中仅didFinish方法被调用一次,其他方法均未触发。后端返回的HTML以<!DOCTYPE html><html lang="en-US"><head><title>Just a moment....开头,以...ld(cpo);}());</script></body></html>结尾。

现有代码实现

WebView结构体

struct WebView: UIViewRepresentable {
    @Environment(\.dismiss) var dismiss
    var url: String?
    var html: String?
    var delegate: WKNavigationDelegate

    init(url: String) {
        self.url = url
        self.delegate = WebViewDelegate()
    }

    init(html: String, successCompletion: @escaping (DismissHandlerState) -> Void) {
        self.html = html
        self.delegate = CookieWebViewDelegate(dismissHandler: successCompletion)
    }
}

makeUIView方法

func makeUIView(context: Context) -> WKWebView {
    let config = WKWebViewConfiguration()
    
    config.preferences.javaScriptCanOpenWindowsAutomatically = true
    config.suppressesIncrementalRendering = true
    let webView: WKWebView
    webView = WKWebView(frame: .zero, configuration: config)
    webView.configuration.defaultWebpagePreferences.allowsContentJavaScript = true
    webView.navigationDelegate = delegate
    webView.evaluateJavaScript("navigator.userAgent") { result, _ in
        if let result = result as? String {
            webView.customUserAgent = result
            CookieWebViewFeature.shared.userAgent = result
        }
    }

    if let url, let rawUrl = URL(string: url) {
        webView.load(URLRequest(url: rawUrl))
    } else if let html {
        webView.loadHTMLString(html, baseURL: Bundle.main.bundleURL)
    }
    
    return webView
}

代理类

final class CookieWebViewDelegate: NSObject, WKNavigationDelegate {
    let dismissHandler: (DismissHandlerState) -> Void
    
    init(dismissHandler: @escaping (DismissHandlerState) -> Void) {
        self.dismissHandler = dismissHandler
    }
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        decisionHandler(.allow)
    }
    
    func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
        if let url = webView.url?.absoluteString {
            print(url)
        }
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print("Page Failed to load: \(error)")
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        let dataStore = WKWebsiteDataStore.default()
        dataStore.httpCookieStore.getAllCookies { cookies in
            print(cookies)
            if CookieWebViewFeature.shared.checkCookie(cookies) {
                self.dismissHandler(.success)
            } else {
                self.dismissHandler(.failed)
            }
        }
    }
}

排查建议

  • 调整User-Agent设置时机:当前在evaluateJavaScript回调中设置customUserAgent,但此时HTML已开始加载,Cloudflare验证可能依赖正确的UA导致逻辑执行异常。建议提前获取默认UA(例如UIDevice.current.userAgent)或构造符合要求的UA后,再加载HTML。
  • 修正baseURL配置:加载HTML时使用Bundle.main.bundleURL作为baseURL,Cloudflare验证脚本可能需要目标站点域名作为基准,导致资源加载或脚本执行失败。尝试将baseURL设置为目标站点的域名URL(如URL(string: "https://your-target-domain.com"))。
  • 优化WKWebView配置:
    • 显式设置config.preferences.javaScriptEnabled = true(部分iOS版本需配合allowsContentJavaScript确保脚本权限)
    • 将suppressesIncrementalRendering改为false,避免阻塞页面渲染
  • 排查脚本执行状态:在didFinish方法中注入脚本,获取页面实际内容或错误信息:
    webView.evaluateJavaScript("document.body.innerHTML") { result, error in
        print("页面内容:", result ?? "无内容")
        print("脚本错误:", error ?? "无错误")
    }
    
  • 补充代理错误回调:添加webView(_:didFailProvisionalNavigation:withError:)方法,捕获加载初期的错误信息:
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        print("临时加载失败:", error.localizedDescription)
    }
    
  • 检查Cookie存储逻辑:Cloudflare验证依赖Cookie,尝试改用WKWebsiteDataStore.nonPersistent()测试是否有旧Cookie干扰,或确保Cookie被正确存储和读取。

内容的提问来源于stack exchange,提问作者Sergey Udalov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:05:19