如何通过webview_flutter读取HttpOnly Cookie或拦截响应?
获取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
相关产品推荐
相关产品推荐

