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’,实际测试发现有效期内就直接使用了缓存页面。
文档信息
- 本文作者:itlgl
- 本文链接:https://itlgl.com/note/2020/03/11/issues-39/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)