layspain21 2025-11-20 17:09 采纳率: 50%
浏览 5

C# 用Xilium.CefGlue 与JS进行通信,监听JS中的方法

C# 用Xilium.CefGlue 与JS进行通信。winForm中 新建一个WebBrowser,再窗体中 打开并显示URL地址后,对JS中得方法和按钮事件进行监听(不是JS调用C#的方法),获取方法的返回值,代码如何实现

  • 写回答

3条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-11-20 19:23
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案能帮助您,请采纳,非常感谢!
    .
    每日一句正能量,让它带给您好心情:生活中的困难,就像一场雨,总会停的,雨后的天空会更蓝。
    .

    在 C# 中使用 Xilium.CefGlue 监听 JavaScript 中的方法和按钮事件,可以通过以下步骤实现:

    1. 创建自定义 Render Process Handler

    public class CustomRenderProcessHandler : CefRenderProcessHandler
    {
        protected override void OnContextCreated(CefBrowser browser, CefFrame frame, CefV8Context context)
        {
            var window = context.GetGlobal();
            
            // 监听 JavaScript 方法调用
            window.SetValue("myJavaScriptMethod", new V8Handler(), CefV8PropertyAttribute.None);
            
            base.OnContextCreated(browser, frame, context);
        }
    }
    
    
    public class V8Handler : CefV8Handler
    {
        protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
        {
            returnValue = CefV8Value.CreateNull();
            exception = null;
            
            if (name == "myJavaScriptMethod")
            {
                // 处理 JavaScript 方法调用
                string result = ProcessJavaScriptCall(arguments);
                returnValue = CefV8Value.CreateString(result);
                return true;
            }
            
            return false;
        }
        
        private string ProcessJavaScriptCall(CefV8Value[] arguments)
        {
            // 处理参数并返回结果
            if (arguments.Length > 0)
            {
                return $"Received: {arguments[0].GetStringValue()}";
            }
            return "No arguments";
        }
    }
    

    2. 创建自定义 Browser Process Handler

    public class CustomBrowserProcessHandler : CefBrowserProcessHandler
    {
        protected override void OnContextInitialized()
        {
            base.OnContextInitialized();
        }
    }
    
    
    public class CustomApp : CefApp
    {
        private readonly CustomRenderProcessHandler _renderProcessHandler = new CustomRenderProcessHandler();
        
        protected override CefRenderProcessHandler GetRenderProcessHandler()
        {
            return _renderProcessHandler;
        }
        
        protected override CefBrowserProcessHandler GetBrowserProcessHandler()
        {
            return new CustomBrowserProcessHandler();
        }
    }
    

    3. 在 WinForm 中实现 CefGlue 浏览器

    public partial class MainForm : Form
    {
        private CefWebBrowser _browser;
        
        public MainForm()
        {
            InitializeComponent();
            InitializeCef();
            InitializeBrowser();
        }
        
        private void InitializeCef()
        {
            var settings = new CefSettings
            {
                MultiThreadedMessageLoop = false,
                SingleProcess = false,
                LogSeverity = CefLogSeverity.Disable,
                WindowlessRenderingEnabled = true
            };
            
            CefRuntime.Initialize(new CefMainArgs(new string[] { }), settings, new CustomApp(), IntPtr.Zero);
        }
        
        private void InitializeBrowser()
        {
            _browser = new CefWebBrowser
            {
                Dock = DockStyle.Fill
            };
            
            this.Controls.Add(_browser);
            
            // 监听浏览器事件
            _browser.LoadEnd += Browser_LoadEnd;
            _browser.ConsoleMessage += Browser_ConsoleMessage;
            
            // 加载 URL
            _browser.LoadUrl("http://your-url-here.com");
        }
        
        private void Browser_LoadEnd(object sender, LoadEndEventArgs e)
        {
            if (e.Frame.IsMain)
            {
                // 页面加载完成后注入监听脚本
                InjectListenerScript();
            }
        }
        
        private void Browser_ConsoleMessage(object sender, ConsoleMessageEventArgs e)
        {
            // 监听控制台消息,可用于接收 JavaScript 事件
            Console.WriteLine($"JS Console: {e.Message} (Line: {e.Line})");
        }
        
        private void InjectListenerScript()
        {
            // 注入 JavaScript 来监听按钮点击和方法调用
            string script = @"
                // 监听按钮点击事件
                document.addEventListener('click', function(e) {
                    if (e.target.tagName === 'BUTTON') {
                        // 调用 C# 方法并传递按钮信息
                        if (typeof myJavaScriptMethod === 'function') {
                            var result = myJavaScriptMethod('Button clicked: ' + e.target.textContent);
                            console.log('C# Response: ' + result);
                        }
                    }
                });
                
                // 监听特定方法调用
                window.originalAlert = window.alert;
                window.alert = function(message) {
                    if (typeof myJavaScriptMethod === 'function') {
                        myJavaScriptMethod('Alert called: ' + message);
                    }
                    window.originalAlert(message);
                };
                
                // 监听表单提交
                document.addEventListener('submit', function(e) {
                    if (typeof myJavaScriptMethod === 'function') {
                        myJavaScriptMethod('Form submitted');
                    }
                });
            ";
            
            _browser.GetMainFrame().ExecuteJavaScript(script, _browser.GetMainFrame().Url, 0);
        }
        
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            CefRuntime.Shutdown();
            base.OnFormClosing(e);
        }
    }
    

    4. 使用 JavaScript 绑定监听特定方法

    private void SetupJavaScriptBindings()
    {
        // 在页面加载后设置更细粒度的监听
        string detailedScript = @"
            // 监听特定按钮
            var specificButton = document.getElementById('myButton');
            if (specificButton) {
                specificButton.addEventListener('click', function() {
                    if (typeof myJavaScriptMethod === 'function') {
                        var returnValue = myJavaScriptMethod('Specific button clicked');
                        console.log('Return value: ' + returnValue);
                    }
                });
            }
            
            // 监听特定函数调用
            var originalFunction = window.someFunction;
            if (originalFunction) {
                window.someFunction = function() {
                    if (typeof myJavaScriptMethod === 'function') {
                        myJavaScriptMethod('someFunction called with args: ' + JSON.stringify(arguments));
                    }
                    return originalFunction.apply(this, arguments);
                };
            }
        ";
        
        _browser.GetMainFrame().ExecuteJavaScript(detailedScript, _browser.GetMainFrame().Url, 0);
    }
    

    5. 处理异步 JavaScript 执行

    private async void ExecuteJavaScriptAndGetResult()
    {
        var task = _browser.EvaluateScriptAsync(@"
            // 执行 JavaScript 并返回结果
            return {
                buttonClicks: document.querySelectorAll('button').length,
                forms: document.forms.length,
                title: document.title
            };
        ");
        
        var result = await task;
        if (result.Success && result.Result != null)
        {
            var data = result.Result;
            // 处理返回的数据
            Console.WriteLine($"页面标题: {data.title}");
        }
    }
    

    关键点说明:

    1. V8Handler 用于处理从 JavaScript 到 C# 的调用
    2. JavaScript 注入 用于设置事件监听器
    3. 控制台消息 可以捕获 JavaScript 的 console.log 输出
    4. 方法重写 可以拦截原有的 JavaScript 函数调用

    这种方法可以有效地监听 JavaScript 中的方法调用和按钮事件,并获取返回值。

    评论

报告相同问题?

问题事件

  • 修改了问题 11月20日
  • 创建了问题 11月20日