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

Flutter webview_flutter:如何通过JavaScript Channel向JS返回数据?

解决webview_flutter双向通信中JS获取Flutter本地存储值的问题

问题核心在于JavaScriptChannel的postMessage是单向通知机制,无法直接向JS返回值,需要通过Promise+Flutter主动调用JS回调的方式实现数据回传。

步骤1:修改JS注入代码

让getName方法返回Promise,同时给每个请求标记唯一ID,把resolve函数暂存到全局,等待Flutter返回数据:

function myCustomObj() {
  this.getName = function() {
    return new Promise((resolve) => {
      // 生成唯一请求ID,避免多请求冲突
      const requestId = 'req_' + Date.now();
      // 把resolve函数存到全局
      window[requestId] = resolve;
      // 向Flutter发送带ID的请求消息
      jsBridge.postMessage(JSON.stringify({
        action: "GET_NAME_FUNCTION",
        requestId: requestId
      }));
    });
  };
}
window.myCustomObj = new myCustomObj();

步骤2:修改Flutter端JavaScriptChannel回调

解析JS传来的消息,获取本地存储值后,主动调用对应的JS回调函数返回数据:

..addJavaScriptChannel('jsBridge', onMessageReceived: (JavaScriptMessage message) async {
  // 解析JSON格式的消息
  final Map<String, dynamic> data = jsonDecode(message.message);
  final String action = data['action'];
  final String requestId = data['requestId'];

  if (action == "GET_NAME_FUNCTION") {
    // 替换为你从本地存储获取值的实际逻辑(比如用shared_preferences)
    String localName = await SharedPreferences.getInstance().then((prefs) => prefs.getString('user_name') ?? '');
    
    // 调用JS的resolve函数回传数据,完成Promise
    await controller.runJavaScript("""
      if (window['$requestId']) {
        window['$requestId']('$localName');
        delete window['$requestId']; // 清理全局变量,避免内存泄漏
      }
    """);
  }
})

步骤3:JS端调用方式

用async/await或者.then()获取返回值:

// 示例调用
async function fetchUserName() {
  const userName = await window.myCustomObj.getName();
  console.log('获取到本地存储的用户名:', userName);
}
fetchUserName();

补充说明

  • 注意处理本地存储获取的异步逻辑,确保拿到值后再调用JS代码。
  • 如果有多个不同的请求类型,可以通过action字段区分,扩展更多通信场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:53:00