【问题标题】:how to return javascript function value from webbrowser c#如何从webbrowser c#返回javascript函数值
【发布时间】:2015-11-27 04:31:49
【问题描述】:

你好 Awesomium 浏览器提供 JavaScript 执行与结果方法来返回这样的值:

private const String JS_FAVICON = "(function(){links = document.getElementsByTagName('link'); wHref=window.location.protocol + '//' + window.location.hostname + '/favicon.ico'; for(i=0; i<links.length; i++){s=links[i].rel; if(s.indexOf('icon') != -1){ wHref = links[i].href }; }; return wHref; })();";
string val = webControl.ExecuteJavascriptWithResult(JS_FAVICON); 

但是我需要使用 c# 内置浏览器执行此操作,如何操作, 我认为有方法“webBrowser1.Document.InvokeScript”不知道如何使用它..

已编辑... 这是 Awesomium 浏览器返回值的方式:

private void Awesomium_Windows_Forms_WebControl_DocumentReady(object  sender, UrlEventArgs e)
    {
        // DOM is ready. We can start looking for a favicon.
        //UpdateFavicon();
    }


 private void UpdateFavicon()
    {
        // Execute some simple javascript that will search for a favicon.
        string val = webControl.ExecuteJavascriptWithResult(JS_FAVICON);

        // Check for any errors.
        if (webControl.GetLastError() != Error.None)
            return;

        // Check if we got a valid response.
        if (String.IsNullOrEmpty(val) || !Uri.IsWellFormedUriString(val, UriKind.Absolute))
            return;

        // We do not need to perform the download of the favicon synchronously.
        // May be a full icon set (thus big).
        Task.Factory.StartNew<Icon>(GetFavicon, val).ContinueWith(t =>
        {
            // If the download completed successfully, set the new favicon.
            // This post-completion procedure is executed synchronously.

            if (t.Exception != null)
                return;

            if (t.Result != null)
                this.Icon = t.Result;

            if (this.DockPanel != null)
                this.DockPanel.Refresh();
        },
        TaskScheduler.FromCurrentSynchronizationContext());
    }

    private static Icon GetFavicon(Object href)
    {
        using (WebClient client = new WebClient())
        {
            Byte[] data = client.DownloadData(href.ToString());

            if ((data == null) || (data.Length <= 0))
                return null;

            using (MemoryStream ms = new MemoryStream(data))
            {
                try
                {
                    return new Icon(ms, 16, 16);
                }
                catch (ArgumentException)
                {
                    // May not be an icon file.
                    using (Bitmap b = new Bitmap(ms))
                        return Icon.FromHandle(b.GetHicon());
                }
            }
        }
    }

这就是我使用 WinForm 浏览器的方式:

 private void webBrowser1_DocumentCompleted(object sender,   WebBrowserDocumentCompletedEventArgs e)
 {
        UpdateFavicon();
 }
 private void UpdateFavicon()
 {
   var obj = webBrowser1.Document.InvokeScript("_X_");
   string val = webBrowser1.DocumentText = "<script> function _X_(){return " + JS_FAVICON + ";} </script>"; 
 }

【问题讨论】:

  • 您指的是哪个 C# 浏览器?您使用的是 WinForms 还是 WPF 或其他任何东西?
  • 之前已经回答过了:stackoverflow.com/questions/1437251/…
  • 我一直在搜索找不到这个抱歉的答案
  • @JohnSmith 如果您认为这是答案,您能否发布您将如何使用没有名称的匿名 javascript 函数来做到这一点。
  • 不可能。您不能调用匿名函数。

标签: javascript c# winforms return-value


【解决方案1】:

正如@JohnSmith 所说,这并非不可能

通过一个简单的技巧,您可以从 javascript 中获取返回值

string JS_FAVICON = "(function(){links = document.getElementsByTagName('link'); wHref=window.location.protocol + '//' + window.location.hostname + '/favicon.ico'; for(i=0; i<links.length; i++){s=links[i].rel; if(s.indexOf('icon') != -1){ wHref = links[i].href }; }; return wHref; })();";

webBrowser1.DocumentCompleted += (s, e) =>
{
    var obj = webBrowser1.Document.InvokeScript("_X_");
    //obj will be about:///favicon.ico
    //write your code that handles the return value here
};

string val = webBrowser1.DocumentText = "<script> function _X_(){return " + JS_FAVICON + ";} </script>";

但是由于我们可以在DocumentCompleted处理程序中获取值,所以不能直接从调用方法中返回它。如果你可以继续你的工作,用那种方法,那没问题。如果没有,那么它需要更多的技巧来完成它。让我知道...

更新

这是完整的工作代码,只需在表单中的某处调用 TestJavascript

async void TestJavascript()
{
    string JS_FAVICON = "(function(){links = document.getElementsByTagName('link'); wHref=window.location.protocol + '//' + window.location.hostname + '/favicon.ico'; for(i=0; i<links.length; i++){s=links[i].rel; if(s.indexOf('icon') != -1){ wHref = links[i].href }; }; return wHref; })();";

    var retval = await Execute(webBrowser1, JS_FAVICON);
    MessageBox.Show(retval.ToString());
}

Task<object> Execute(WebBrowser wb,  string anonJsFunc)
{
    var tcs = new TaskCompletionSource<object>();
    WebBrowserDocumentCompletedEventHandler documentCompleted = null;
    documentCompleted = (s, e) =>
    {
        var obj = wb.Document.InvokeScript("_X_");
        tcs.TrySetResult(obj);
        wb.DocumentCompleted -= documentCompleted; //detach
    };

    wb.DocumentCompleted += documentCompleted; //attach
    string val = wb.DocumentText = "<script> function _X_(){return " +
                                    anonJsFunc +
                                    ";} </script>";

    return tcs.Task;
}

【讨论】:

  • @jsem 你想让我用我的水晶球看看你的代码并回答吗?
  • @jsem 您的代码错误。在我的示例中,我首先设置 webBrowser1.DocumentText 并在 DocumentCompleted 事件中调用 InvokeScript BTW:请参阅我的更新...
  • @jsem 你最后的评论是什么?我什么都不懂。我不知道我还能做什么。我发布了一个准备复制和粘贴的代码。如果您无法管理它来运行它,忽略可能会回答,我会删除它。
  • 它不断循环运行时错误,对不起所有麻烦我疯了
猜你喜欢
  • 2016-10-08
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 2011-10-29
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 2016-08-28
相关资源
最近更新 更多