Flutter Cache Manager配置后未命中缓存始终发起网络请求问题
flutter_cache_manager 缓存永不生效修复方案
核心问题原因
validTill 始终为过去时间、缓存永远不命中,由三类常见问题触发:
- 传入的请求头包含禁用缓存字段:若
headers中携带Cache-Control: no-cache/Pragma: no-cache配置,插件会直接绕过本地缓存校验强制拉取网络资源,且不会更新对应缓存条目的validTill值。 - 资源URL存在动态参数:自行构造的Uri如果每次请求都携带动态生成的query参数(比如时间戳、随机串、动态签名),插件会将参数不同的URL识别为全新资源,历史缓存条目因URL不匹配永远无法被命中,自然不会触发
validTill更新。 - 服务端响应头覆盖本地缓存配置:默认
HttpFileService会优先读取服务端返回的Cache-Control/Expires头计算validTill,如果服务端返回no-store、max-age=0或过期的Expires值,会直接覆盖你在Config中配置的stalePeriod,最终计算出的validTill永远是过去时间。
落地修复步骤
- 排查清理请求头:移除headers中所有禁用缓存的字段,测试阶段可先传入空headers验证基础缓存逻辑是否正常,认证类固定头不影响缓存逻辑可保留。
- 固定缓存匹配key:如果业务必须在URL中携带动态签名、时间戳参数,不要直接用完整
uri.toString()作为缓存匹配键,调用getSingleFile时传入固定key,剔除动态变化的参数部分:
final file = await instance.getSingleFile( uri.toString(), headers: headers, // 用资源固定路径作为缓存key,去掉动态query参数 key: '${uri.scheme}://${uri.host}${uri.path}', ); final bytes = await file.readAsBytes();
- 覆写响应过期时间逻辑,强制使用本地配置的缓存有效期,避免被服务端响应头干扰:
// 自定义文件服务 class FixedCacheHttpFileService extends HttpFileService { @override Future<FileServiceResponse> get(String url, {Map<String, String>? headers}) async { final originResponse = await super.get(url, headers: headers); return _FixedCacheResponse(originResponse); } } class _FixedCacheResponse implements FileServiceResponse { final FileServiceResponse _origin; _FixedCacheResponse(this._origin); @override Stream<List<int>> get content => _origin.content; @override int get contentLength => _origin.contentLength; @override String? get eTag => _origin.eTag; @override String get fileExtension => _origin.fileExtension; @override int get statusCode => _origin.statusCode; // 强制使用配置的7小时有效期,忽略服务端返回的禁缓存头 @override DateTime get validTill => DateTime.now().add(const Duration(hours: 7)); }
替换初始化Config中的fileService配置:
Config( key, stalePeriod: const Duration(hours: 7), maxNrOfCacheObjects: 50, repo: JsonCacheInfoRepository(databaseName: key), // 替换为自定义的文件服务 fileService: FixedCacheHttpFileService(), );
- 验证逻辑:首次调用完成文件下载后,重启应用再次发起请求,确认无网络请求发起、直接返回本地缓存文件即可,也可直接查询缓存库中对应条目的
validTill字段,确认值为当前时间加7小时的未来时间即修复完成。
内容的提问来源于stack exchange,提问作者Arash
相关产品推荐
相关产品推荐

