Flutter InAppWebView 设置用户令牌Cookie时页面无限刷新问题
循环刷新问题根因
- 原有逻辑将Cookie设置、主动加载页面的操作全部绑定在
onLoadStop回调中:该回调在页面每一次加载完成时都会触发,执行完设置Cookie动作后又主动调用loadUrl发起新的页面请求,新请求加载完成后会再次触发onLoadStop,形成无终止条件的无限刷新循环 - 依赖JS在页面加载完成后设置Cookie的时机不合理:页面发起初始请求时还没有注入令牌Cookie,这也是为什么之前必须手动刷新才能让Cookie生效的核心原因
- 代码中定义的
expiresDate变量未被实际使用,写入Cookie时缺少过期时间配置,同时原JS字符串语法存在错误:把secure、sameSite等Cookie属性用分号拆成了独立语句,并没有实际附加到Cookie配置中
可落地优化方案
优先使用flutter_inappwebview提供的原生CookieManager完成Cookie注入,从根源上避免循环问题:
- 将Cookie设置逻辑前置到WebView初始化阶段,在正式加载目标URL之前完成令牌Cookie的写入,让页面首次发起请求时就自动携带对应Cookie,完全不需要额外刷新页面
调整后的核心代码片段:// 类成员变量定义 InAppWebViewController _webViewController; final expiresDate = DateTime.now().add(Duration(days: 3)).millisecondsSinceEpoch; // 修改onWebViewCreated回调逻辑 onWebViewCreated: (InAppWebViewController controller) async { _webViewController = controller; final token = await getToken(); // 原生API写入Cookie,无需依赖JS执行 await CookieManager.instance().setCookie( url: widget.url, name: "accessToken", value: token, expiresDate: expiresDate, isSecure: true, isHttpOnly: false, sameSite: HTTPCookieSameSitePolicy.NONE, ); // Cookie全部写入完成后再加载目标URL await controller.loadUrl(url: widget.url); } - 移除
onLoadStop回调中所有涉及Cookie写入、主动调用loadUrl/reload的逻辑,仅保留页面加载完成后的常规交互(比如隐藏加载提示、触发页面埋点等),从逻辑上断掉循环触发的链路
调整后的onLoadStop示例:onLoadStop: (InAppWebViewController controller, url) async { // 仅保留非触发刷新的常规逻辑,不再主动发起页面加载请求 } - 若业务场景确实需要在页面加载完成后补写Cookie,必须增加单次执行标记位,避免重复触发:
类中新增标记变量bool _hasSetCookie = false,在onLoadStop进入时先判断标记位,若Cookie已完成写入则直接跳过后续逻辑,仅在第一次进入回调时执行一次Cookie写入+页面刷新操作,执行完成后立刻将标记位置为true
示例代码:bool _hasSetCookie = false; onLoadStop: (InAppWebViewController controller, url) async { if (_hasSetCookie) return; try { final token = await getToken(); await CookieManager.instance().setCookie( url: url, name: "accessToken", value: token, expiresDate: expiresDate, isSecure: true, isHttpOnly: false, sameSite: HTTPCookieSameSitePolicy.NONE, ); _hasSetCookie = true; await controller.reload(); } catch (e) { print(e.toString()); } }
注意事项
- 优先使用原生Cookie API设置令牌,不要依赖JS执行
document.cookie:JS设置的Cookie受跨域策略、SameSite限制影响大,容易出现失效问题,且时机难以精准控制 - 设置Cookie时需要保证传入的URL域名与待加载的业务页面域名匹配,否则Cookie不会被携带到对应域名的请求中
- 原JS写Cookie的语法存在硬伤:
'document.cookie = "accessToken=${token}"; secure=true; httpOnly=false; sameSite=None'中,分号后续的secure等属性属于独立语句,并没有被附加到Cookie配置中,即使不做循环逻辑的调整,这种写法也无法正确生效
内容的提问来源于stack exchange,提问作者Salma
相关产品推荐
相关产品推荐

