itlgl / note

使用github的issues功能记录日常的笔记
http://itlgl.com/note
5 stars 2 forks source link

flutter webview 加载页面时设置自定义cookie #39

Open itlgl opened 4 years ago

itlgl commented 4 years ago

flutter提供了一个插件来显示webview:flutter_webview_plugin: 0.3.10+1

这个插件没有直接提供类似android上的CookieManager来直接操作cookie,但是提供了一个方法'flutterWebViewPlugin.evalJavascript'执行js,可以通过这个方法,执行js代码,将cookie设置进去,然后刷新网页即可。

代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';

class TestWebViewRoute extends StatelessWidget {

  FlutterWebviewPlugin flutterWebViewPlugin = FlutterWebviewPlugin();

  @override
  Widget build(BuildContext context) {

    setCookieToHtml();

    return WebviewScaffold(
      url: 'https://www.baidu.com',
      appBar: AppBar(
        title: Text('Test'),
      ),
      withZoom: true,
      withLocalStorage: true,
      withJavascript: true,
    );
  }

  void setCookieToHtml() {
    flutterWebViewPlugin.onStateChanged.listen((viewState) async {
      if (viewState.type == WebViewState.finishLoad) {
        Map<String, dynamic> cookies = await flutterWebViewPlugin.getCookies();
        bool isHasCookie = false;
        if(cookies != null) {
          cookies.forEach((key, value) {
            print('cookie key=$key, value=$value');
            // 因为获取到的key前面带了一个空格,所以直接用containsKey方法判断一直返回false
            if(key.trim() == 'JSESSIONID_TEST') {
              isHasCookie = true;
            }
          });
        }
        if(!isHasCookie) {
          print('set cookie');
          flutterWebViewPlugin.evalJavascript(
            '''
var name = "JSESSIONID_TEST";
var value = "i am session id";
var days = 1; //定义一天
var exp = new Date();
exp.setTime(exp.getTime() + days * 24 * 60 * 60 * 1000);
// 写入Cookie, toGMTString将时间转换成字符串
document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString() + ";path=/" + ";domain=www.baidu.com";
            '''
          );
          flutterWebViewPlugin.reload();
        }
      }
    });
  }
}

这段代码还设置了'LocalStorage'为true,期望效果是没有网时可以离线打开网页,但是并没有起作用,网页并没有缓存。 在一个博客上找到了原因,因为缓存策略会判断网页头中的'cache-control'字段来判断是否从网络上获取数据,而百度的网页这个字段设置的就是'no-cache'不让缓存,导致每次都会重新获取网页内容。 那么要缓存网页有两种方法,一种是把网页数据直接用文件存起来,下次判断未过期直接使用,一种就是和后台协商修改这个字段。 如果将网址修改为'https://itlgl.com/'就可以缓存了,因为github的网页特意设置了缓存策略'cache-control: max-age=600',实际测试发现有效期内就直接使用了缓存页面。