Flutter Chrome扩展:弹窗未激活时Dart与Service Worker通信方案咨询
背景
我正使用Flutter(借助FlutterFlow)开发一款支持iOS、Android及Chrome扩展的密码管理器应用。
构建信息
- manifest V3
- Flutter 3.13.7(FlutterFlow当前使用版本)
- Chrome版本:120.0.6099.234
当前状态
已完成popup.html和manifest.json配置,成功将Flutter应用作为Chrome扩展启动;目前可通过弹窗利用FlutterFlow自定义action中的chrome_extension Flutter包捕获当前标签页信息。
目标
建立Service Worker与编译为main.dart.js的Dart代码之间的通信通道,要求弹窗未打开时仍能正常工作。
核心问题
Flutter将main.dart编译为main.dart.js,该文件作为popup.html的主体资源,仅在弹窗激活时加载。我需要在弹窗未激活时检查当前网站的可用用户凭证,但用户认证信息、凭证查询函数等逻辑都封装在main.dart.js中,弹窗未激活时无法访问。未找到弹窗未激活时Service Worker/Content Script与Dart代码通信的有效方法。考虑过将用户认证信息存储到Chrome Storage中,在main.dart.js外的文件中执行数据库查询,但不确定该方案的实用性与安全性。
已尝试方案
实现了Content Script和Service Worker的简单sendMessage函数,以及Dart侧的监听器,但弹窗未激活时会报错:Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.;弹窗激活时,Content Script与Dart代码可正常通信。
测试代码
content_script.js
// Send a message to the service worker chrome.runtime.sendMessage({greeting: 'Hello from content script'}, (response) => { console.log('Received response in content script:', response); });
service_worker.js
// Listen for messages from the content script chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { console.log('Service Worker: Received message:', message); var messageFromSE = 'Hello from Service Worker'; // Forward the message to the Dart code and listen for a response chrome.runtime.sendMessage(messageFromSE, (responseFromDart) => { console.log('Service Worker: Received response from Dart:', responseFromDart); // Send the response back to the content script sendResponse(responseFromDart); }); // Return true to indicate that you wish to send a response asynchronously return true; });
FlutterFlow自定义action(编译到main.dart.js)
import 'dart:async'; import 'dart:js' as js; import 'dart:convert'; import 'package:chrome_extension/runtime.dart' as chrome_ext; Future<void> listenForMessagesFromServiceWorker() async { chrome_ext.chrome.runtime.onMessage.listen((chrome_ext.OnMessageEvent e) { print('Dart: Received message from Service Worker: ${e.message}'); // Process the message and send a response back var response = {'greeting': 'Hello back from Dart'}; e.sendResponse(js.JsObject.jsify(response)); }); // Return a future that never completes to keep the listener active return Future.value(); }
该Dart函数已添加到main.dart的应用初始化动作中,确保应用启动时监听器立即激活。
内容的提问来源于stack exchange,提问作者Baptman

