You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:57:58