MAUI怎么从JavaScript调用C#代码 WebView与MAUI通信

8次阅读

MAUI 中 JS 调用 C#推荐使用 WebMessage 跨平台方案,通过 WebView.WebMessageReceived 事件接收消息、PostWebMessageAsync 发送响应;Android/iOS 可选 RegisterScriptableObject 但不跨平台;C# 调 JS 统一用 EvaluateJavaScriptAsync。

MAUI 怎么从 JavaScript 调用 C# 代码 WebView 与 MAUI 通信

MAUI 中通过 WebView 实现 JavaScript 调用 C# 代码,核心是使用 WebView.EvaluateJavaScriptAsync 配合 WebView.RegisterScriptableObject(仅限 Android/iOS)或更通用的 WebView.PostWebMessageAsync / WebMessageReceived(推荐跨平台方案)。但注意:MAUI 的 WebView 默认不支持直接注册 JS 对象(如 UWP/WinUI 风格),需按平台适配,主流且稳定的方式是基于 WebMessage 的双向通信。

使用 WebMessage 实现 JS → C#(推荐跨平台)

这是 MAUI 官方推荐、全平台(Android、iOS、Windows、macOS)都支持的方式,无需平台特定代码,依赖 WebView.WebMessageReceived 事件和 JS 端的 window.chrome.webview.postMessage(Windows)或通用 webkit.messageHandlers(iOS)等——但 MAUI 封装后统一为 postMessage 调用。

  • 在 XAML 或 C# 中启用 WebView 并订阅事件:
  • C# 端处理消息:

private void OnWebMessageReceived(object sender, WebMessageReceivedEventArgs e)
{
  string message = e.WebMessageAsJson; // 自动转为 JSON 字符串
  // 解析并响应,例如:
  if (message.Contains(“getUserName”))
  {
    webView.PostWebMessageAsString(JsonSerializer.Serialize(new { result = “Alice”}));
  }
}

  • JS 端发送消息(网页中):
    window.addEventListener(“DOMContentLoaded”, () => {
      window.chrome?.webview?.postMessage?.({cmd: “getUserName”});
      // 或兼容写法(MAUI 内部会自动映射):
      if (typeof window.webkit !== ‘undefined’ && window.webkit.messageHandlers) {
        window.webkit.messageHandlers.external.postMessage({cmd: “getUserName”});
      } else {
        window.chrome?.webview?.postMessage?.({cmd: “getUserName”});
      }
    });
  • 注意:MAUI 的 WebView 在 Windows 上使用 WebView2,iOS 使用 WKWebView,JS 发送方式略有差异,但 PostWebMessageAsStringWebMessageReceived 在 C# 层已统一抽象,JS 端建议优先用 window.chrome?.webview?.postMessage(MAUI 6+ 已注入兼容逻辑)。

Android/iOS 原生桥接(RegisterScriptableObject,有限支持)

该方式类似 Xamarin.Forms 的 RegisterScriptableObject,但在 MAUI 中仅对 Android 和 iOS 有效(Windows/macOS 不支持),且需自定义 WebViewHandler 注入对象。

立即学习 Java 免费学习笔记(深入)”;

  • 定义一个 C# 类并标记 [System.Runtime.InteropServices.ComVisible(true)]

[System.Runtime.InteropServices.ComVisible(true)]
public class JsBridge
{
  public string GetTime() => DateTime.Now.ToString();
  public void Log(string msg) => Debug.WriteLine($”JS said: {msg}”);
}

  • 在 Android 平台代码中(Platforms/Android/MainActivity.cs)注册:

var bridge = new JsBridge();
webView.Handler.PlatformView?.AddJavascriptInterface(bridge, “bridge”);

  • JS 中调用:
    bridge.GetTime(); // 注意大小写和括号
  • iOS 需配合 WKScriptMessageHandler + WKUserContentController,实现更复杂,不推荐新手直接使用。

从 C# 主动调用 JS(反向通信)

无论用哪种 JS→C# 方式,C# 都可通过 WebView.EvaluateJavaScriptAsync 执行任意 JS 代码,实现反向调用:

  • 例如通知网页加载完成:
    await webView.EvaluateJavaScriptAsync(“window.appReady && window.appReady();”);
  • 传递数据(需转义):
    string data = JsonSerializer.Serialize(new { id = 123, name = “Test”});
    await webView.EvaluateJavaScriptAsync($”window.receiveData({data});”);
  • 注意:JS 函数必须已在网页中全局定义,否则静默失败;建议加 try/catch 包裹 JS 端逻辑。

注意事项与避坑点

  • WebView 必须已加载完成(NavigationCompleted 事件后)再注册监听或调用 JS,否则可能失效。
  • JSON 数据传输时,确保字符串合法,避免单引号、未转义换行等;建议统一用 JsonSerializer.SerializeJsonSerializer.Deserialize
  • 调试 JS→C# 通信:在 JS 中加 console.log,C# 中加 Debug.WriteLine,确认消息是否发出 / 收到。
  • 不要依赖 window.external(IE 时代遗留),MAUI 不支持;也不要尝试直接访问 window.bridge 除非你明确做了 Android 原生桥接。

基本上就这些。WebMessage 是最稳的起点,够用且可扩展;原生桥适合有特殊性能或深度集成需求的场景。不复杂但容易忽略加载时机和 JSON 格式细节。

星耀云
版权声明:本站原创文章,由 星耀云 2026-01-03发表,共计2854字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources