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

如何通过webview_flutter读取HttpOnly Cookie或拦截响应?

处理webview_flutter中HttpOnly Cookie获取及响应头监听问题

HttpOnly Cookie的设计初衷就是禁止前端JS读取,所以无法通过webview_flutter的JS注入方式直接获取,必须通过原生平台API获取后,再通过MethodChannel传递给Flutter端:

Android 端实现

利用系统CookieManager类获取包含HttpOnly在内的所有Cookie,通过MethodChannel暴露给Flutter:

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.yourapp/cookie"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getCookie") {
                val url = call.argument<String>("url") ?: ""
                val cookie = CookieManager.getInstance().getCookie(url)
                result.success(cookie)
            } else {
                result.notImplemented()
            }
        }
    }
}

iOS 端实现

通过HTTPCookieStorage获取目标URL的Cookie,同样通过MethodChannel传递:

@objc class MainFlutterViewController: FlutterViewController {
    private let CHANNEL = "com.yourapp/cookie"

    override func viewDidLoad() {
        super.viewDidLoad()
        let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: self.binaryMessenger)
        channel.setMethodCallHandler { [weak self] call, result in
            if call.method == "getCookie" {
                guard let urlStr = call.arguments as? String, let url = URL(string: urlStr) else {
                    result(FlutterError(code: "INVALID_URL", message: "无效URL", details: nil))
                    return
                }
                let cookies = HTTPCookieStorage.shared.cookies(for: url) ?? []
                let cookieString = cookies.map { "\($0.name)=\($0.value)" }.joined(separator: "; ")
                result(cookieString)
            } else {
                result(FlutterMethodNotImplemented)
            }
        }
    }
}

Flutter 端调用

统一调用原生方法获取Cookie:

const platform = MethodChannel('com.yourapp/cookie');

Future<String?> getTargetCookie(String targetUrl) async {
  try {
    return await platform.invokeMethod('getCookie', {'url': targetUrl});
  } on PlatformException catch (_) {
    return null;
  }
}

监听URL响应头

webview_flutter本身没有直接提供响应头监听API,需要通过原生层拦截请求获取响应头,再传递给Flutter:

Android 端拦截

自定义WebViewClient重写onReceivedHttpHeaders方法,获取响应头后通过MethodChannel通知Flutter:

override fun onReceivedHttpHeaders(view: WebView?, url: String?, response: WebResourceResponse?) {
    super.onReceivedHttpHeaders(view, url, response)
    response?.responseHeaders?.let { headers ->
        channel.invokeMethod("onReceivedHeaders", mapOf("url" to url, "headers" to headers))
    }
}

iOS 端拦截

通过WKNavigationDelegate的didFinishNavigation方法获取响应头:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("document.URL") { result, _ in
        guard let urlStr = result as? String, let url = URL(string: urlStr),
              let response = url.response as? HTTPURLResponse else {
            return
        }
        let headers = response.allHeaderFields as? [String: String] ?? [:]
        self.channel.invokeMethod("onReceivedHeaders", arguments: ["url": urlStr, "headers": headers])
    }
}

Flutter 端监听响应头

在Flutter端注册MethodChannel回调处理响应头:

platform.setMethodCallHandler((call) async {
    if (call.method == 'onReceivedHeaders') {
        final String url = call.arguments['url'] as String;
        final Map<String, dynamic> headers = Map.from(call.arguments['headers'] as Map);
        // 在这里处理拿到的响应头
    }
});

注意事项

  • 确保传递的URL与Cookie所属域名完全匹配
  • 原生与Flutter端的MethodChannel名称必须一致
  • iOS端若访问HTTP域名,需在info.plist中配置NSAppTransportSecurity允许非HTTPS请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:55:30