Flutter WebView如何实现JS回调

我在Flutter中使用了WebView加载网页,现在需要在网页中调用JavaScript方法后,将结果回调到Flutter端。请问应该如何实现这个JS回调功能?目前尝试了官方推荐的JavaScriptChannel,但不知道如何正确接收和处理回调数据。能否提供一个具体的实现示例,包括如何注册回调方法和处理返回数据?

2 回复

使用flutter_inappwebview插件,在InAppWebView中设置onJsAlertonJsConfirm等回调方法,通过JavaScriptHandler处理JS与Flutter通信。

更多关于Flutter WebView如何实现JS回调的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter WebView中实现JS回调,主要有以下几种方式:

1. 使用官方webview_flutter插件

import 'package:webview_flutter/webview_flutter.dart';

WebViewController _controller = WebViewController()
  ..setJavaScriptMode(JavaScriptMode.unrestricted)
  ..addJavaScriptChannel(
    'Flutter',
    onMessageReceived: (JavaScriptMessage message) {
      // 处理来自JS的回调
      print('收到JS消息: ${message.message}');
    },
  )
  ..loadRequest(Uri.parse('https://example.com'));

在HTML/JS中调用:

Flutter.postMessage('Hello from JavaScript');

2. 使用url_launcher + JavaScript通道

// 在WebView中
_controller..setNavigationDelegate(NavigationDelegate(
  onUrlChange: (UrlChange change) {
    if (change.url != null) {
      // 解析URL参数获取回调数据
      Uri uri = Uri.parse(change.url!);
      if (uri.scheme == 'myapp') {
        String data = uri.queryParameters['data'] ?? '';
        print('收到回调数据: $data');
      }
    }
  },
));

// JS中调用
window.location.href = 'myapp://callback?data=' + encodeURIComponent(jsonData);

3. 完整的双向通信示例

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late final WebViewController _controller;

  @override
  void initState() {
    super.initState();
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..addJavaScriptChannel(
        'MessageHandler',
        onMessageReceived: (JavaScriptMessage message) {
          // 处理JS回调
          handleJSCallback(message.message);
        },
      )
      ..loadFlutterAsset('assets/webpage.html');
  }

  void handleJSCallback(String message) {
    print('JS回调: $message');
    // 处理业务逻辑
  }

  // 从Flutter调用JS
  void callJavaScript() async {
    await _controller.runJavaScript('flutterCallback("来自Flutter的消息")');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: WebViewWidget(controller: _controller),
      floatingActionButton: FloatingActionButton(
        onPressed: callJavaScript,
        child: Icon(Icons.message),
      ),
    );
  }
}

对应的HTML文件:

<!DOCTYPE html>
<html>
<body>
  <button onclick="sendToFlutter()">发送到Flutter</button>
  
  <script>
    function sendToFlutter() {
      // 调用Flutter
      MessageHandler.postMessage(JSON.stringify({
        type: 'button_click',
        data: '用户点击了按钮'
      }));
    }

    // Flutter调用的函数
    function flutterCallback(message) {
      alert('收到Flutter消息: ' + message);
    }
  </script>
</body>
</html>

关键点说明:

  1. JavaScript通道:使用addJavaScriptChannel注册通道,JS通过ChannelName.postMessage()调用
  2. 双向通信:Flutter可以调用runJavaScript执行JS代码
  3. 数据类型:建议使用JSON格式传输复杂数据
  4. 安全性:注意验证来自JS的数据,防止安全漏洞

选择哪种方式取决于具体需求,官方webview_flutter插件是最推荐的方式。

回到顶部