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

在WKWebView中加载登录页后,能否获取登录成功的JSON数据?

在WKWebView中获取登录成功后的JSON数据

可以获取,下面是两种实用的实现方案:

方案一:JS注入与原生交互

这种方法适配性强,不管前端是否可控都能实现:

1. 配置原生消息处理器

先给WKWebView添加消息监听,接收前端传递的登录数据:

class LoginWebVC: UIViewController, WKScriptMessageHandler {
    private var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let config = WKWebViewConfiguration()
        // 注册接收JS消息的处理器
        config.userContentController.add(self, name: "loginSuccessBridge")
        
        webView = WKWebView(frame: view.bounds, configuration: config)
        webView.navigationDelegate = self
        view.addSubview(webView)
        
        // 加载目标登录页面
        webView.load(URLRequest(url: URL(string: "你的登录页面地址")!))
    }

    // 接收JS发送的登录数据
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard message.name == "loginSuccessBridge", let loginJSON = message.body as? [String: Any] else {
            return
        }
        // 这里拿到登录相关的JSON数据,做后续处理
        print("登录返回数据:\(loginJSON)")
    }
}

2. 注入JS监听登录请求

在页面加载完成后,注入JS脚本拦截登录接口的响应,自动把数据传给原生:

extension LoginWebVC: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        // 注入监听XMLHttpRequest的脚本,替换成你的登录接口路径
        let injectScript = """
        const originSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.send = function() {
            const xhr = this;
            xhr.addEventListener('load', function() {
                if (xhr.responseURL.includes('/api/user/login')) {
                    try {
                        const loginData = JSON.parse(xhr.responseText);
                        window.webkit.messageHandlers.loginSuccessBridge.postMessage(loginData);
                    } catch(e) {}
                }
            });
            originSend.apply(this, arguments);
        };
        """
        webView.evaluateJavaScript(injectScript) { _, error in
            if let err = error { print("JS注入失败:\(err)") }
        }
    }
}

如果前端是你可控的,也可以让前端在登录成功后直接调用window.webkit.messageHandlers.loginSuccessBridge.postMessage(loginResult)传递数据,省去注入脚本的步骤。

方案二:拦截网络请求响应

通过自定义WKURLSchemeHandler拦截WKWebView的登录接口请求,直接获取响应数据:

1. 实现自定义Scheme处理器

class LoginSchemeHandler: NSObject, WKURLSchemeHandler {
    func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
        let request = urlSchemeTask.request
        guard let url = request.url, url.path.contains("/api/user/login") else {
            // 非登录接口,直接转发请求
            let task = URLSession.shared.dataTask(with: request) { data, resp, err in
                self.forwardResponse(to: urlSchemeTask, data: data, response: resp, error: err)
            }
            task.resume()
            return
        }

        // 处理登录接口请求,提取响应数据
        let task = URLSession.shared.dataTask(with: request) { data, resp, err in
            if let data = data, let httpResp = resp as? HTTPURLResponse, httpResp.statusCode == 200 {
                do {
                    let loginJSON = try JSONSerialization.jsonObject(with: data) as? [String: Any]
                    print("登录数据:\(loginJSON ?? [:])")
                    // 可通过通知或闭包把数据传递给控制器
                    NotificationCenter.default.post(name: .loginSuccess, object: loginJSON)
                } catch { print("解析登录数据失败:\(error)") }
            }
            self.forwardResponse(to: urlSchemeTask, data: data, response: resp, error: err)
        }
        task.resume()
    }

    func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {}

    // 把响应转发给WKWebView,保证页面正常流程
    private func forwardResponse(to task: WKURLSchemeTask, data: Data?, response: URLResponse?, error: Error?) {
        if let resp = response { task.didReceive(resp) }
        if let data = data { task.didReceive(data) }
        if let err = error {
            task.didFailWithError(err)
        } else {
            task.didFinish()
        }
    }
}

// 定义通知名
extension Notification.Name {
    static let loginSuccess = Notification.Name("LoginSuccessNotification")
}

2. 配置WKWebView使用自定义处理器

// 在控制器中创建WKWebView时
let config = WKWebViewConfiguration()
// 给https协议(或你的接口协议)绑定自定义处理器
config.setURLSchemeHandler(LoginSchemeHandler(), forURLScheme: "https")
webView = WKWebView(frame: view.bounds, configuration: config)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:25:20