Flutter Web应用如何在浏览器local storage存储对象列表实现数据持久化
Flutter Web 多账号持久化存储实现方案
你要实现关闭浏览器后数据不丢失的存储能力,优先选择浏览器原生的localStorage,它属于持久化存储,只要用户不主动清除对应站点的缓存数据,数据会一直保留。目前有两种常用实现方案:
方案1:使用官方推荐的 shared_preferences 包(最简便,适配多端)
这个是Flutter官方维护的跨端存储方案,Web端底层默认基于localStorage实现,不需要单独处理Web侧逻辑,适配性最好。
- 第一步在
pubspec.yaml中引入依赖:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2 # 可替换为最新稳定版本
- 第二步定义账号实体和存取逻辑,因为localStorage仅支持存储字符串类型,所以需要把多账号列表转成JSON字符串存储:
import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; // 账号实体示例,可根据业务需求扩展字段 class UserAccount { final String userId; final String email; final String avatar; final String accessToken; final String refreshToken; bool isActive; // 标记是否为当前登录的激活账号 UserAccount({ required this.userId, required this.email, required this.avatar, required this.accessToken, required this.refreshToken, this.isActive = false, }); Map<String, dynamic> toJson() => { 'userId': userId, 'email': email, 'avatar': avatar, 'accessToken': accessToken, 'refreshToken': refreshToken, 'isActive': isActive, }; factory UserAccount.fromJson(Map<String, dynamic> json) => UserAccount( userId: json['userId'], email: json['email'], avatar: json['avatar'], accessToken: json['accessToken'], refreshToken: json['refreshToken'], isActive: json['isActive'] ?? false, ); } // 保存多账号列表到本地存储 Future<void> saveAccountList(List<UserAccount> accounts) async { final prefs = await SharedPreferences.getInstance(); final accountJsonStr = jsonEncode(accounts.map((e) => e.toJson()).toList()); await prefs.setString('global_user_account_list', accountJsonStr); } // 从本地存储读取多账号列表 Future<List<UserAccount>> getAccountList() async { final prefs = await SharedPreferences.getInstance(); final accountStr = prefs.getString('global_user_account_list'); if (accountStr == null) return []; final List<dynamic> jsonList = jsonDecode(accountStr); return jsonList.map((e) => UserAccount.fromJson(e)).toList(); }
- 新增/切换/删除账号的逻辑只需要修改内存中的账号列表,再调用
saveAccountList回写存储即可。
方案2:直接调用浏览器原生localStorage(更灵活,仅Web端可用)
如果你不需要适配移动端,只想针对Web端做更轻量的实现,可以直接调用dart:html提供的原生API,不需要引入第三方依赖:
import 'dart:html'; import 'dart:convert'; // 存账号列表 void saveAccountListNative(List<UserAccount> accounts) { final accountJsonStr = jsonEncode(accounts.map((e) => e.toJson()).toList()); window.localStorage['global_user_account_list'] = accountJsonStr; } // 读账号列表 List<UserAccount> getAccountListNative() { final accountStr = window.localStorage['global_user_account_list']; if (accountStr == null) return []; final List<dynamic> jsonList = jsonDecode(accountStr); return jsonList.map((e) => UserAccount.fromJson(e)).toList(); }
注意事项
- 敏感信息加密:accessToken、用户隐私信息不要明文存储,建议使用对称加密算法加密后再写入存储,避免XSS攻击导致数据泄露
- 存储上限:localStorage的单站点总存储上限一般为5MB,仅存储账号基础信息即可,不要存入大体积的二进制资源
- 多账号数据隔离:如果不同账号的业务数据需要分开存储,可以给业务存储的key加上
${userId}_前缀,避免不同账号数据混乱 - 退出逻辑:单账号退出时仅删除列表中对应账号数据再回写即可,不要清空整个存储,保留其他账号的登录信息
内容的提问来源于stack exchange,提问作者wahab sohail
相关产品推荐
相关产品推荐

