Flutter Webview添加Cookie的正确姿势
场景
h5页面要从cookie里面取数据,所以需要在flutter webview的cookie里面塞一些数据,设置的数据多达十几条;按照网上查的使用方式来设置,通过fiddler抓包发现,只能生效一条,来来回回试了很多次都只有一条,心态崩了
后来看到cookie设置数据也是类似键值对里面套键值对,灵机一动,变换下后就成功了,记录下正确的写法吧
正确姿势
引入
- 使用的是flutter官方维护的webview插件
webview_flutter: ^0.3.22+1
错误示例
- 这是最坑的一个,widget都都没写全,就写了俩个回调,这么写只会生效一条
WebViewController _controller;
onWebViewCreated: (WebViewController wvc) {
_controller = wvc;
}
onPageFinished: (String value) {
_controller.evaluateJavascript( 'document.cookie = "SESSIONID=612bc4822b6996d6f335a963c20eb541fba72985; path=/"')
}
- 这个只写了一条cookie,这个是没问题的,和上面的区别就是,这个使用双引号包住单引号,只写了一条的使用也是让人肝痛
setSessionID() async {
String sessionID = await LocalStorage.get("sessionID");
if (Platform.isIOS) {
_controller.evaluateJavascript("document.cookie = 'sessionID=${sessionID}'").then<String>((res) {
print("webViewController.evaluateJavascript========>${res}");
_onListCookies(_controller, context);
});
} else {
_controller.evaluateJavascript('document.cookie = "sessionID=${sessionID};"').then<String>((res) {
print("webViewController.evaluateJavascript========>${res}");
_onListCookies(_controller, context);
});
}
}
多条cookie添加正确写法
- 琢磨半天试出来的正确写法,cookie的设置需要在页面加载完之后设置
///webview控制器
WebViewController _controller;
String _url = "写入你的链接";
WebView(
initialUrl: _url,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) {
_controller = controller;
},
onPageFinished: (url) {
//页面加载结束
String cookie =
"document.cookie = 'name=IAmDaShuaiBi';document.cookie = 'id=233'";
_controller.evaluateJavascript(cookie);
},
userAgent: "test;app/1.0.0",
)
- 最重要的变化就是每条cookie都要用document.cookie作为key,这是最最最关键的
优化写法
- 上面的写法是写成一行,写成一行是很致命的操作,让赋值操作会变得很迷惑,优化下
///webview控制器
WebViewController _controller;
String _url = "写入你的链接";
WebView(
initialUrl: _url,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) {
_controller = controller;
},
onPageFinished: (url) {
//页面加载结束
String cookie = '''
document.cookie = 'nameOne=IAmDaShuaiBi';
document.cookie = 'idOne=233';
document.cookie = 'nameTwo=IAmDaShuaiBi';
document.cookie = 'idTwo=233';
document.cookie = 'nameThree=IAmDaShuaiBi';
document.cookie = 'idThree=233';
''';
_controller.evaluateJavascript(cookie);
},
userAgent: "test;app/1.0.0",
)
- ok,搞定
补充
- 就这么点内容就水了一片文章,显得我是个水笔,为了证明我不是个水笔,再补充个开发小技巧
弹窗封装,优化列表数据源
说明
底部单列表弹窗是非常实用的弹窗,但是可能大家经常有这样的一种使用体验,传数据源,一般都是传一个List类型,内部的泛型最最最常见的就是:String和固定的实体;说下这俩种情况的问题所在
- String:显然该泛型,内部处理处理起来非常简单,直接拿String值展示就行,回调直接把选择的String返回;这种String类型存在一个非常致命的的问题,在使用前后都存在问题
- 使用前:我们必须把数据类型转换成List类型,我们数据源一般都是通过接口获取,接口里面List数据源里面的泛型五花八门的,往往需要做循环转化成List类型去使用
- 使用后:点击选择后,拿到我们选择的展示名,接口提交往往是需要该种选择类型的id,一般来说还需要去做遍历拿出选择名称对应的id,然后保存做提交操作
- 规定实体:使用规定的泛型实体,有一个好处,可以避免在使用后去遍历对比,然后去取id的操作,所以他只存在使用前的麻烦
- 使用前:这里我们必须把拿到的数据源转换符合要求的List规定实体泛型,这步操作就可以把id等信息一起放在规定的实体里面,选择之后也可以直接从实体里面拿了
吐槽:虽然上面俩种情况,第二种明显优于第一种,但是实际开发中,往往不假思索的用第一种,因为第一种不用去新建一个class啊!然后用起来就蛋痛了;有没有一种方法可以一劳永逸的方法呢,数据的list泛型随便用,只用指定泛型实体用于展示的key;然后在回调里面又能拿到我们传的实体呢?通过dart强大的动态类型,加一些巧妙转换是完全可以的
实现思路
java里可以通过泛型+反射;然后指定一个展示的key,理论上也是可以实现,我没试过,大家可以试试
实现思路
实现方法还是很简单的,这里说下思路就行了
实现步骤
- 数据源定义为List类型,然后指定一个展示的key
- 泛型不指定的话,会默认为动态类型,这样的话,便有了很大的操作空间
- 遍历这个List,然后拿到遍历列表时的实体
- 将实体转换成Map类型,通过指定的key,获取展示内容就行了
- 回调时,传出来选的实体就ok,似不似很简单
举例
- 引入:flutter_picker
flutter_picker: ^1.1.5
- 实现
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_picker/Picker.dart';
typedef ParamSingleCallback<E> = Void Function(E data);
void showBottomSingleDialog<E>(
BuildContext context, {
@required List<E> list,
@required ParamSingleCallback<E> callback,
String title = '请选择',
String showKey = '',
}) {
List<PickerItem<E>> pickList = [];
for (E item in list) {
String showContent;
if (showKey == '') {
//兼容泛型为String的情况
showContent = item as String;
} else {
//将实体转成map,通过设置的key指定展示的字段
var map = json.decode(jsonEncode(item));
showContent = map[showKey];
}
pickList.add(
PickerItem(
text: Text(showContent),
value: item,
),
);
}
Picker(
adapter: PickerDataAdapter<E>(data: pickList),
hideHeader: false,
title: Text(title),
cancelText: "取消",
confirmText: "确定",
onConfirm: (Picker picker, List value) async {
//必须做一个延时操作,先执行回调内部的pop,不然pop页面无法回传值
await Future.delayed(Duration(milliseconds: 10));
callback(picker.getSelectedValues()[0]);
},
).showModal(context);
}
使用
- 数据源
class InfoBean {
String name;
int id;
InfoBean({this.id, this.name});
/// jsonDecode(jsonStr) 方法中会调用实体类的这个方法。如果实体类中没有这个方法,会报错。
Map toJson() {
Map map = Map();
map["name"] = this.name;
map["id"] = this.id;
return map;
}
}
///创建数据源
List<InfoBean> list = [];
for (var i = 0; i < 10; i++) {
list.add(InfoBean(name: "姓名-$i", id: i));
}
- 使用
- 这地方指不指定泛型都是可以的,不指定泛型默认为动态类型,item点的时候没有提示,可以凭着自己的记忆写key值,只要是key是对,完全能拿到数据
///指定泛型
showBottomSingleDialog<InfoBean>(
context,
list: list,
showKey: 'name',
callback: (item) {
print(item.name);
print(item.id);
},
);
///不指定泛型
showBottomSingleDialog(
context,
list: list,
showKey: 'name',
callback: (item) {
print(item.name);
print(item.id);
},
);


最后
代码地址
- Github:范例项目代码地址
Flutter Webview添加Cookie的正确姿势的更多相关文章
- Sql动态添加字段的正确姿势
如何给指定表动态添加字段? 一.创建一张表[Tbl_AutoFileds] (tableName表名,fieldName字段名,dataType数据类型,length长度 isnull 是否允许为n ...
- element动态添加表头的正确姿势
1. 第一步循环 el-table-column <el-table-column v-if="item.show" v-for="(item, index) in ...
- GitHub 热点速览 Vol.18:刷 LeetCode 的正确姿势
作者:HelloGitHub-小鱼干 摘要:找对路子,事半功倍,正如本周 GitHub Trending #刷 LeetCode# 主题想表达的那般,正确的学习姿势方能让人走得更远,走进大厂
- ios监听ScrollView/TableView滚动的正确姿势
主要介绍 监测tableView垂直滚动的舒畅姿势 监测scrollView/collectionView横向滚动的正确姿势 1.监测tableView垂直滚动的舒畅姿势 通常我们用KVO或者在scr ...
- selenium3.7+ python3 添加cookie模拟登陆
一.背景介绍 最近做一个爬虫项目,用selenium调用浏览器去获取渲染后的源码,但是每次登陆都需要手机验证,这真的是头痛啊,这种验证方式不要想着去破解,还是老老实实用手机收验证码去吧!反正我是不知道 ...
- 使用 win10 的正确姿势
17年9月初,写了第一篇<使用 win10 的正确姿势>,而现在半年多过去,觉得文章得更新一些了,索性直接来个第二版吧. -----2018.3.24 写 一. 重新定义桌面 我的桌面: ...
- 使用 win10 的正确姿势 (第二版)
文章为本人原创,转载请注明出处,谢谢. 17年9月初,写了第一篇<使用 win10 的正确姿势>,而现在半年多过去,文章更新了一些,主要是桌面的变化. 一. 重新定义桌面 我的桌面: 将桌 ...
- 开发函数计算的正确姿势 —— 使用 Fun Local 本地运行与调试
前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算 ...
- 【分布式缓存系列】Redis实现分布式锁的正确姿势
一.前言 在我们日常工作中,除了Spring和Mybatis外,用到最多无外乎分布式缓存框架——Redis.但是很多工作很多年的朋友对Redis还处于一个最基础的使用和认识.所以我就像把自己对分布式缓 ...
随机推荐
- 送命题:讲一讲Mybatis插件的原理及如何实现?
持续原创输出,点击上方蓝字关注我吧 目录 前言 环境配置 什么是插件? 如何自定义插件? 举个栗子 用到哪些注解? 如何注入Mybatis? 测试 插件原理分析 如何生成代理对象? 如何执行? 总结 ...
- 面试官写了个双冒号: : 问我这是什么语法?Java中有这玩意?
一:简洁 方法引用分为三种,方法引用通过一对双冒号:: 来表示,方法引用是一种函数式接口的另一种书写方式 静态方法引用,通过类名::静态方法名, 如 Integer::parseInt 实例方法引用, ...
- 大白话谈JVM的类加载机制
前言 我们很多小伙伴平时都是做JAVA开发的,那么作为一名合格的工程师,你是否有仔细的思考过JVM的运行原理呢. 如果懂得了JVM的运行原理和内存模型,像是一些JVM调优.垃圾回收机制等等的问题我们才 ...
- Python对象的空间边界:独善其身与开放包容
导读:Python猫是一只喵星来客,它爱地球的一切,特别爱优雅而无所不能的 Python.我是它的人类朋友豌豆花下猫,被授权润色与发表它的文章.如果你是第一次看到这个系列文章,那我强烈建议,请先看看它 ...
- obj2opengl:转换OBJ 3D模型到iPhone OpenGL ES兼容的数组中
原文如下:obj2opengl: convert obj 3D models to arrays compatible with iPhone OpenGL ES obj2opengl在GitHub中 ...
- Unity Shader 00 - 梳理 Unity Shader 的基本结构
0x00 写在前面 之前一直在阅读 The Book of Shaders 一书,为什么会开始写 Unity Shader 呢?一方面,因为该书目前尚未完结,写下此文时已阅读到该书的最新章节:另一方面 ...
- Object.assign()的使用
一.Object.assign()对象的拷贝 1 Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象. 2 Object.assign(ta ...
- Jmeter之『如果(If)控制器』
判断方法 ${__jexl3("${projectName}"=="${targetDir}",)} ${__groovy("${projectNam ...
- Recursive sequence (矩阵快速幂)2016ACM/ICPC亚洲区沈阳站
题目 Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recu ...
- RHSA-2017:2299-中危: NetworkManager 和 libnl3 安全和BUG修复更新(本地提权、代码执行)
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...