Flutter how to get all Cookies from a webview, and make dio request with that cookies

Viewed 511

Issue Description and Steps

  1. There's a Webview which I will load a url first.
  2. Then I would like to make dio request with the cookies stored in webview's request. How to do it ?

in Objetive-C

To make cookie shared, corresponding Objetive-C code are very simple:

  NSHTTPCookieStorage *sharedHTTPCookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
  NSArray<NSHTTPCookie*>* cookies = [sharedHTTPCookieStorage cookiesForURL:[NSURL URLWithString:url]];
  [sharedHTTPCookieStorage setCookies: cookies
                               forURL:[NSURL URLWithString:@"https://m.weibo.cn/"]
                      mainDocumentURL:nil];

In Flutter

I can find CookieManager, but it looks like not work in this case. And I didn't find the sharedHTTPCookieStorage which used do do this in iOS.

Any suggestion would appreciate.

Sample code

dependencies:
  flutter:
    sdk: flutter
  system_proxy: ^0.1.0
  flutter_inappwebview: ^5.3.2

  dio: ^4.0.0
  cookie_jar: 3.0.1
  dio_cookie_manager: ^2.0.0
  path_provider: 2.0.2
import 'dart:io';

import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart' as cm;
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: MyPage());
  }
}

class MyPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  final _dio = Dio();

  @override
  void initState() {
    super.initState();
    setupCookieManager();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        test(),
        _buildButton(),
      ],
    );
  }

  _onClick() async {
    try {
      final res = await _dio.get('/api/users/show');

      if (res.data != null) {
        print('_onClick.data: ${res.data}');
      } else {
        print('_onClick.error: ${res.data}');
      }
    } catch (e) {
      print('_onClick.catch: $e');
    }
  }

  Widget _buildButton() {
    return Positioned(
      left: 0,
      right: 0,
      bottom: 100,
      child: Center(
        child: TextButton(
          onPressed: _onClick,
          child: const Text('Click'),
          style: TextButton.styleFrom(
            textStyle: const TextStyle(fontSize: 20, color: Colors.red),
            backgroundColor: Colors.yellow,
          ),
        ),
      ),
    );
  }

  Widget test() {
    return InAppWebView(
      initialUrlRequest: URLRequest(
        url: Uri.https(host2, ''),
      ),
      onWebViewCreated: (InAppWebViewController controller) {
        // _webViewController = controller;
      },
      onLoadStart: (c, url) {
        print('onLoadStart: $url');
      },
      onLoadError: (c, url, code, msg) {
        print('onLoadError: $url, $code, $msg');
      },
      onLoadStop: (c, url) async {
        print('onLoadStop: $url');
        final _webviewCookies =
            await CookieManager.instance().ios.getAllCookies();
        print('CookieManager.instance/cookies: $_webviewCookies');

        print('setupCookies...');
      },
    );
  }

  setupCookieManager() async {
    _dio.interceptors.add(LogInterceptor());
    _dio.options.receiveTimeout = 10000;

    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path;

    final cj = PersistCookieJar(
        ignoreExpires: true, storage: FileStorage(appDocPath + "/.cookies/"));
    _dio.interceptors.add(cm.CookieManager(cj));

    _dio.options..baseUrl = host;
  }

  static String get host => 'https://m.weibo.cn/'; 
  static String get host2 => 'm.weibo.cn';
}
0 Answers
Related