You need to enable JavaScript to run this app. Flutter InAppWebView 设置用户令牌Cookie时页面无限刷新问题
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 12:24:03