如何在flutter_inappwebview清除缓存后维持登录状态?(版本^6.0.0-beta.23)
解决方案
核心问题是你当前的代码在清除WebView缓存后才从WebView中获取Cookie,但此时WebView的Cookie已经被清除,重新设置的是无效值,自然无法保留登录状态。正确的做法是提前将登录Cookie持久化到本地存储,清除缓存后再从本地读取并恢复到WebView中。
具体实现步骤
1. 添加本地存储依赖
在pubspec.yaml中添加shared_preferences用于持久化Cookie:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2 flutter_inappwebview: ^6.0.0-beta.23
2. 登录成功后保存Cookie到本地
在用户登录成功、WebView获取到有效登录Cookie时,将所需Cookie保存到本地:
import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; // 登录成功后执行此逻辑 Future<void> saveLoginCookies(String webUrl) async { CookieManager cookieManager = CookieManager.instance(); // 获取当前WebView的所有Cookie List<Cookie> cookies = await cookieManager.getCookies(url: WebUri(webUrl)); // 筛选出登录所需的t1和r1 Cookie Cookie? t1Cookie = cookies.firstWhere((c) => c.name == "t1", orElse: () => Cookie(name: "", value: "")); Cookie? r1Cookie = cookies.firstWhere((c) => c.name == "r1", orElse: () => Cookie(name: "", value: "")); // 将Cookie转为JSON字符串保存到本地 SharedPreferences prefs = await SharedPreferences.getInstance(); if (t1Cookie.value.isNotEmpty) { await prefs.setString("t1_cookie", jsonEncode(t1Cookie.toJson())); } if (r1Cookie.value.isNotEmpty) { await prefs.setString("r1_cookie", jsonEncode(r1Cookie.toJson())); } }
3. 清除缓存后恢复Cookie到WebView
在清除WebView缓存后,从本地读取保存的Cookie并重新设置到WebView:
Future<void> restoreLoginCookies(InAppWebViewController webViewController, String webUrl) async { // 清除WebView缓存 await webViewController.clearCache(); CookieManager cookieManager = CookieManager.instance(); SharedPreferences prefs = await SharedPreferences.getInstance(); // 恢复t1 Cookie String? t1Json = prefs.getString("t1_cookie"); if (t1Json != null) { Map<String, dynamic> t1Map = jsonDecode(t1Json); await cookieManager.setCookie( url: WebUri(webUrl), name: t1Map["name"], value: t1Map["value"], domain: t1Map["domain"] ?? "www.careturtle.com", isSecure: t1Map["isSecure"] ?? true, expires: t1Map["expires"] != null ? DateTime.fromMillisecondsSinceEpoch(t1Map["expires"]) : null, maxAge: t1Map["maxAge"], path: t1Map["path"] ?? "/", // 确保路径匹配,通常网站用根路径"/" webViewController: webViewController, ); } // 恢复r1 Cookie String? r1Json = prefs.getString("r1_cookie"); if (r1Json != null) { Map<String, dynamic> r1Map = jsonDecode(r1Json); await cookieManager.setCookie( url: WebUri(webUrl), name: r1Map["name"], value: r1Map["value"], domain: r1Map["domain"] ?? "www.careturtle.com", isSecure: r1Map["isSecure"] ?? true, expires: r1Map["expires"] != null ? DateTime.fromMillisecondsSinceEpoch(r1Map["expires"]) : null, maxAge: r1Map["maxAge"], path: r1Map["path"] ?? "/", webViewController: webViewController, ); } // 加载目标网页 await webViewController.loadUrl(urlRequest: URLRequest(url: WebUri(webUrl))); }
关键注意事项
- 不要在清除缓存后读取WebView的Cookie:
clearCache()会清除WebView的所有缓存数据,包括Cookie,此时获取的Cookie是无效值,无法用于恢复登录状态。 - 确保Cookie属性完全匹配:网站返回的Cookie可能包含
path、expires、maxAge等属性,恢复时要完整设置,否则Cookie可能无法被网站识别。 - 检查域名格式:如果网站使用泛域名Cookie(比如
.careturtle.com),设置domain时要使用该泛域名,而不是www.careturtle.com,否则跨子域访问时Cookie不生效。 - 会话Cookie的特殊处理:如果网站返回的是会话Cookie(无
expires或maxAge),清除WebView缓存后会话会失效,这种情况需要后端支持持久化Cookie,或者通过refresh token重新获取登录会话。
内容的提问来源于stack exchange,提问作者Nutty Blogs
相关产品推荐
相关产品推荐

