Flutter WebView 4.0.2中WebViewCookieManager.setCookie在iOS端失效求助
此前使用flutter_webview 3版本时,Cookie认证功能正常,近期升级至flutter_webview 4后,Cookie认证出现异常。目前已完成大部分迁移工作,但该问题未解决,不确定是库本身的问题还是代码迁移存在疏漏。
已知情况
- Flutter WebView 3.x 的
initialCookies在iOS和Android端均能正常完成认证; - 使用
WebViewCookieManager.setCookie初始化Cookie在Android端可正常生效; - iOS端通过
WebViewController.loadRequest携带Header仅对初始URL有效,点击页面内按钮后认证失效并退出登录。
代码示例
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:webview_cookie_manager/webview_cookie_manager.dart'; import 'package:webview_flutter/webview_flutter.dart'; // Import for Android features. import 'package:webview_flutter_android/webview_flutter_android.dart'; // Import for iOS features. import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; class WebViewPage extends StatefulWidget { const WebViewPage({super.key}); @override State<WebViewPage> createState() => _WebViewPageState(); } class _WebViewPageState extends State<WebViewPage> { late final WebViewController controller; late final WebViewCookieManager cookieManager; bool isLoading = false; Map<String, String>? headers; // 替换为实际业务域名 final String _baseUrl = "https://your-business-domain.com"; @override void initState() { super.initState(); // 平台化Cookie管理器初始化 var cookieParams = const PlatformWebViewCookieManagerCreationParams(); if (WebViewPlatform.instance is WebKitWebViewPlatform) { cookieParams = WebKitWebViewCookieManagerCreationParams .fromPlatformWebViewCookieManagerCreationParams( cookieParams, ); } else if (WebViewPlatform.instance is AndroidWebViewPlatform) { cookieParams = AndroidWebViewCookieManagerCreationParams .fromPlatformWebViewCookieManagerCreationParams( cookieParams, ); } cookieManager = WebViewCookieManager.fromPlatformCreationParams( cookieParams, ); // 平台化WebViewController初始化 var params = const PlatformWebViewControllerCreationParams(); if (WebViewPlatform.instance is WebKitWebViewPlatform) { params = WebKitWebViewControllerCreationParams .fromPlatformWebViewControllerCreationParams( params, ); } else if (WebViewPlatform.instance is AndroidWebViewPlatform) { params = AndroidWebViewControllerCreationParams .fromPlatformWebViewControllerCreationParams( params, ); } final initController = WebViewController.fromPlatformCreationParams(params) ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setBackgroundColor(const Color.fromARGB(0, 255, 255, 255)) ..setNavigationDelegate( NavigationDelegate( onProgress: (int progress) { setState(() { isLoading = true; }); }, onPageStarted: (String url) {}, onPageFinished: (String url) { setState(() { isLoading = false; }); }, onWebResourceError: (WebResourceError error) {}, onNavigationRequest: (NavigationRequest request) { return NavigationDecision.navigate; }, ), ); controller = initController; getPreferenceData(); } Future<void> getPreferenceData() async { final prefs = await SharedPreferences.getInstance(); // COOKIE = {'ID': 123, 'TOKEN': 'abcd'} final cookieHashString = prefs.getString('COOKIE') ?? ''; if (cookieHashString != '') { final cookieHash = json.decode(cookieHashString); headers = <String, String>{ 'Cookie': 'TOKEN=${cookieHash["TOKEN"]};ID=${cookieHash["ID"]};' }; await setWebViewCookie(headers!, cookieHash); } } Future<void> setWebViewCookie( Map<String, String> headers, Map<String, dynamic> cookieHash, ) async { // Android端需此方式设置Cookie,iOS端不生效 // iOS端靠loadRequest携带Header完成初始认证,但页面内点击按钮后认证失效 await cookieManager.setCookie( WebViewCookie( name: 'ID', value: cookieHash['ID'].toString(), domain: _baseUrl.replaceAll(RegExp(r'^https?://'), ''), ), ); await cookieManager.setCookie( WebViewCookie( name: 'TOKEN', value: cookieHash['TOKEN'].toString(), domain: _baseUrl.replaceAll(RegExp(r'^https?://'), ''), ), ); // iOS端必须通过此Header完成初始认证 await controller.loadRequest( Uri.parse('$_baseUrl/member/'), headers: headers, ); } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { // 处理Android物理返回键 if (await controller.canGoBack()) { await controller.goBack(); return false; } return true; }, child: Scaffold( body: SafeArea( child: Stack( children: [ WebViewWidget( controller: controller, ), if (isLoading) const Center(child: CircularProgressIndicator()) else const SizedBox.shrink(), ], ), ), ), ); } }
内容的提问来源于stack exchange,提问作者Glitch_Znab
相关产品推荐
相关产品推荐

