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

Flutter Web与Android端如何接收WebView的postMessage消息?

Flutter Web与Android端统一接收iframe postMessage消息解决方案

我开发的Flutter应用需展示iframe内容并接收其消息:Web端通过IFrameElement+HtmlElementView配合window.addEventListener能正常捕获postMessage,但Android端用webview_flutter的JavaScriptChannel收不到消息。核心差异在于:

  • Web端里,iframe的window.parent就是Flutter Web的全局window,消息直接被监听捕获
  • Android端里,iframe的window.parent是WebView加载页面的window,消息无法直接传递到Flutter的通道层

以下是两种可行的双端兼容方案:

方案一:修改iframe代码适配双端(有权限修改iframe时用)

在iframe的发送逻辑里判断运行环境,分别用不同方式发消息:

// iframe中的消息发送代码
if (typeof window.FlutterMessageChannel !== 'undefined') {
  // Android WebView环境,调用Flutter注册的通道
  window.FlutterMessageChannel.postMessage(JSON.stringify(data));
} else {
  // Web端环境,发送给parent
  window.parent.postMessage(data, '*');
}

Web端保持原有监听逻辑不变,Android端代码只需确保注册的通道名称和iframe里的一致(比如示例中的FlutterMessageChannel),即可正常接收。

方案二:WebView注入JS转发消息(无法修改iframe时用)

如果没法改iframe代码,就在WebView页面加载完成后注入JS,监听当前页面的message事件,把iframe发来的消息转发到Flutter通道:

修改后的Android端代码:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class ShowView extends StatefulWidget {
  const ShowView({super.key});

  @override
  State<ShowView> createState() => _ShowViewState();
}

class _ShowViewState extends State<ShowView> {
  late WebViewController controller;

  @override
  void initState() {
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..addJavaScriptChannel(
        'FlutterMessageChannel',
        onMessageReceived: (JavaScriptMessage message) {
          print('收到消息: ${message.message}');
        },
      )
      ..setNavigationDelegate(
        NavigationDelegate(
          onPageFinished: (_) {
            // 注入监听逻辑
            controller.runJavaScript('''
              window.addEventListener('message', (event) => {
                window.FlutterMessageChannel.postMessage(JSON.stringify(event.data));
              });
            ''');
          },
        ),
      )
      ..loadRequest(Uri.parse('<URL>'));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return WebViewWidget(controller: controller);
  }
}

Web端代码无需改动,保持原来的window.addEventListener监听即可。

方案选择建议

  • 能修改iframe代码时优先选方案一,逻辑更直接,避免额外的JS注入
  • 无法修改iframe时选方案二,通过WebView的JS注入实现消息中转

内容的提问来源于stack exchange,提问作者myme

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 11:53:10