代码之家  ›  专栏  ›  技术社区  ›  dylanT

来自CefSharp中iframe的返回.net调用被阻止

  •  0
  • dylanT  · 技术社区  · 8 年前

    我有一个场景,我在cefsharp browser中调用JavaScript方法,然后该JavaScript方法调用postMessage将消息发送到另一个域上的iframe,然后iframe调用代码库中的.Net方法,通知它完成了它正在做的事情。

    这是C#end of things的一个例子:

    // This class can be called by Javascript from cefSharp browser
    public class BrowserListener
    {
        public BrowserListener()
        {
        }
        public void SendBool(bool result)
        {
            // This line doesn't get hit until after the timeout period
            Log.Logger.Debug("Bool received from iframe {result}", result);
            Shared.Result = result;
            Shared.Received = true;
        }
    }
    
    public static class Shared
    {
        // Only done this way for demonstration purposes
        public static bool Received {get; set;} = false;
        public static bool Result {get; set;} = false;
    }
    
    public class winCefBrowser : Window, IRequestHandler, IDownloadHandler, ILifeSpanHandler, IJsDialogHandler, ILoadHandler, IDialogHandler, IRenderProcessMessageHandler
    {
        // snipped a lot of interface implementation
        private ChromiumWebBrowser mActiveView;
    
        public winCefBrowser(IKiraSession activeSession)
        {
            CefSettings settings = new CefSettings();
            settings.RemoteDebuggingPort = 1212;
            settings.IgnoreCertificateErrors = false;
            if (!Cef.IsInitialized)
            {
                Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
            }
            var v = new ChromiumWebBrowser();
            var s = new BrowserSettings();
            s.ImageLoading = CefState.Disabled;
            v.BrowserSettings = s;
            v.RequestContext = new RequestContext();
            mActiveView = v;
            // We have a tab control with the browser tab on it
            var loNewTab = new TabItem { Header = "New" };
            tabBrowser.Items.Add(loNewTab);
    
            mActiveView.DownloadHandler = this;
            mActiveView.RequestHandler = this;
            mActiveView.LifeSpanHandler = this;
            mActiveView.JsDialogHandler = this;
            mActiveView.LoadHandler = this;
            mActiveView.DialogHandler = this;
    
            var opt = new BindingOptions {CamelCaseJavascriptNames = false};
    
            mActiveView.RegisterAsyncJsObject("ourNet", new BrowserListener(),opt);
    
            loNewTab.Content = mActiveView;
    
        }
    
        public async Task<bool> DoStuff(string myString)
        {
            Shared.Received = false;
            var jsResponse = await mActiveView.EvaluateScriptAsync("myMethod('" + myString "');");
            if (jsResponse.Result != "OK") return false;
            var t = new Stopwatch();
            t.Start();
    
            // THIS LOOP IS WHERE THE PROBLEM IS
            // The code will loop around here for 10 seconds, then return false
            // THEN the call is received from the javascript method.
            while (!Shared.Received)
            {
                Thread.Sleep(100);
                if (t.Elapsed.Seconds > 10)
                {
                    // Shouldn't hit this line
                    Log.Logger.Debug("Timed out waiting for response from inner javascript call.");
                    return false;
                }
            }
            // Never hits this line
            return Shared.Result;
        }
    }
    

    此代码位于html主页面上:

    function myMethod(message) {
        // Simplified, this posts to the first iframe on the page
        var x = document.getElementsByTagName("iframe")[0].contentWindow;
        if (x !== null && x !== undefined) {
            x.postMessage(message, "*");
        }
        return "OK";
    }
    

    if (window.addEventListener) {
        window.addEventListener("message", myListen, true);
    } else {
        window.attachEvent("onmessage", myListen);
    }
    
    function myListen(event) {
        if (event.data == null) return;
        // These log messages appear almost immediately in the debug console at http://localhost:1212
        console.log("myListen triggered with event data:");
        console.log(event.data);
    
        ourNet.SendBool(true);
    
        // This final log message is hit straight away. 
        // But .Net doesn't start processing the call to SendBool for 10 seconds.
        console.log("Call back to .net completed.");
    }
    

    我正在WPF中使用CefSharp进行测试。我们的最终目标是在屏幕外运行这个程序,所以如果这是WPF特有的东西,我不介意知道。

    0 回复  |  直到 8 年前