You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 08:15:00