Flutter中InAppWebView的JavaScript处理及WebView与Flutter数据交互
在Flutter InAppWebView中处理JavaScript与数据交互
一、启用JavaScript支持
首先必须在InAppWebView的初始配置中开启JS支持,否则网页端JS代码无法执行:
InAppWebView( initialUrlRequest: URLRequest(url: Uri.parse("https://your-target-page.com")), initialSettings: InAppWebViewSettings( javaScriptEnabled: true, // 核心配置:开启JS javaScriptCanOpenWindowsAutomatically: false, // 根据业务需求调整 ), )
二、网页端向Flutter传递数据(Web→Flutter)
推荐两种规范的实现方式:
1. 官方推荐:注册JavaScript Handler
Flutter端先注册专属Handler,用于接收网页端的调用:
InAppWebView( onWebViewCreated: (controller) { // 注册名为"sendDataToFlutter"的处理函数 controller.addJavaScriptHandler( handlerName: 'sendDataToFlutter', callback: (args) { // args是网页端传递的参数数组,取第一个元素即可 final webData = args.first; // 在这里处理网页数据,比如更新本地状态、触发原生逻辑 print('收到网页数据:$webData'); // 可选:返回响应给网页端 return "Flutter已接收数据:${webData['userId']}"; }, ); }, // 其他配置... )
网页端JS调用该Handler完成数据传递:
// 调用Flutter注册的Handler,传入数据并接收响应 window.flutter_inappwebview.callHandler('sendDataToFlutter', { userId: 1001, userName: 'test_user', action: 'login_success' }).then(response => { console.log('Flutter返回的响应:', response); });
2. 简易方案:通过Console消息传递
适合快速原型或简单场景,网页端将数据封装在特定格式的console.log中:
// 用自定义协议前缀标记消息,避免与普通日志混淆 console.log('flutter://web-message?data=' + JSON.stringify({type: 'notify', content: 'page_loaded'}));
Flutter端监听控制台消息并解析:
InAppWebView( onConsoleMessage: (controller, consoleMessage) { final message = consoleMessage.message; if (message.startsWith('flutter://')) { final uri = Uri.parse(message); final dataStr = uri.queryParameters['data']; if (dataStr != null) { try { final data = jsonDecode(dataStr); print('解析到网页消息:$data'); } catch (e) { print('数据解析失败:$e'); } } } return Future.value(true); }, // 其他配置... )
三、Flutter主动调用JavaScript代码
如果需要Flutter触发网页端的JS逻辑,使用evaluateJavascript方法:
// 示例:调用网页端的自定义函数并获取返回值 final jsResult = await webViewController.evaluateJavascript( source: "window.getWebPageInfo('flutter_trigger');" ); print('JS执行结果:$jsResult');
四、JavaScript管理注意事项
- 安全校验:接收网页数据时必须做格式校验,用
try-catch包裹JSON解析逻辑,避免恶意数据导致崩溃。 - Handler清理:在页面销毁时移除已注册的Handler,防止内存泄漏:
@override void dispose() { webViewController?.removeJavaScriptHandler(handlerName: 'sendDataToFlutter'); super.dispose(); }
- 命名空间隔离:网页端尽量将交互方法放在自定义命名空间下(比如
window.flutterBridge = {}),避免与全局变量冲突。 - 版本兼容:不同版本的
inappwebview包API可能存在差异,建议使用最新稳定版并参考官方文档调整代码。
内容的提问来源于stack exchange,提问作者K K Muhammed Fazil
相关产品推荐
相关产品推荐

