cefsharp 关于C# 调用JavaScript的一个坑

之前开发的一个产品在上线后总有奇怪的BUG,经过一番调试后发现在使用CEF控件的

EvaluateScriptAsync

这个方法的时候,并不能保证成功.

经过一番查询,发现官方文档(https://github.com/cefsharp/CefSharp/wiki/General-Usage#devtools)有这么一段

2. How do you call a JavaScript method that returns a result?

If you need to evaluate code which returns a value, use the Task<JavascriptResponse> EvaluateScriptAsync(string script, TimeSpan? timeout) method. JavaScript code is executed asynchronously and as such uses the .Net Task class to return a response, which contains error message, result and a success (bool) flag.

// Get Document Height
var task = frame.EvaluateScriptAsync("(function() { var body = document.body, html = document.documentElement; return  Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); })();", null);

task.ContinueWith(t =>
{
    if (!t.IsFaulted)
    {
        var response = t.Result;
        EvaluateJavaScriptResult = response.Success ? (response.Result ?? "null") : response.Message;
    }
}, TaskScheduler.FromCurrentSynchronizationContext());

For a more detailed example check out this Gist

Notes

  • Scripts are executed at the frame level, and every page has at least one frame (MainFrame)
  • Only trivial values can be returned (like int, bool, string etc) - not a complex (user-defined) type which you have defined yourself. This is because there is no (easy) way to expose a random JavaScript object to the .NET world, at least not today. However, one possible technique is to turn the JavaScript object you wish to return to your .NET code into a JSON string with the JavaScript JSON.toStringify() method and return that string to your .NET code. Then you can decode that string into a .NET object with something like JSON.NET. See this MSDN link for more information. (https://msdn.microsoft.com/en-us/library/ie/cc836459(v=vs.94).aspx)

可以用这种方式获取到JS的返回值:

1 task.ContinueWith(t =>
2 {
3     if (!t.IsFaulted)
4     {
5         var response = t.Result;
6         EvaluateJavaScriptResult = response.Success ? (response.Result ?? "null") : response.Message;
7     }
8 }, TaskScheduler.FromCurrentSynchronizationContext());

于是利用这一点,做了个"流水ID"

每次调用的时候就+1,另一头代码执行完后,返回该ID,如果调用失败(或者返回的ID无法识别),则重新发起,如果另一头收到连续两次一样的ID,则不做处理(但还是要返回ID的.).

这样个方法也能用来解决某些丢包问题.

时间: 2024-10-20 05:04:05

cefsharp 关于C# 调用JavaScript的一个坑的相关文章

困扰多日的C#调用Haskell问题竟然是Windows的一个坑

最近一直被C#调用Haskell时的"尝试读取或写入受保护的内存"问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected memory,C#调用haskell时的"尝试读取或写入受保护的内存"问题),而且困在其中,越陷超深,无法自拔,差点弃用C#解决我们面临的问题. 问题是这样的,只要在Haskell代码中对字符串进行操作,在C#调用时就会引发异常: An unhandled exception of ty

50 tips of JavaScript,这些坑你都知道吗?

1.在局部作用域中,使用var操作符定义的变量将成为定义该变量的作用域中的局部变量,省略var的会创建全局变量:在全局作用域中,不管是否使用var操作符定义的变量都会创建一个全局变量.但是,在全局作用域中使用var创建的全局变量是不能被delete删除的,而未使用var创建的变量和局部作用域中未使用var操作符创建的全局变量是可以删除的.(与其说省略var会创建全局变量,倒不如说省略var会直接给全局对象添加一个新的属性,因为ES中的变量只能通过var关键字才能创建): var a = 1; /

在 Flash ActionScript 2.0 中调用 Javascript 方法

本篇文章由:http://xinpure.com/call-the-javascript-method-in-flash-actionscript-2-0/ 在 Flash ActionScript 2.0 中调用 Javascript 方法 最近在工作中,有个这样的需求: 要从 Flash ActionScript 2.0 中调用网页上的 Javascript 方法 这是一个关于 Flash 和 Javascript 交互的问题. 在 ActionScript 2.0 中调用外部 javasc

Android 和Java API的一个坑:SimpleDateFormat

今天上班遇到这么一个意料之外的异常: 出问题的代码是这样的(已去除上下文信息): Log.i(LOG_TAG, new SimpleDateFormat("YYYY-MM-dd HH:mm:ss", Locale.CHINA) .format(System.currentTimeMillis())); 反复检查,感觉没有问题,于是新建一个Java Project,直接输出同样的代码: public class Main{ public static void main(String[]

java调用javascript :js引擎rhino

java调用javascript :js引擎rhino JavaJavaScriptEclipse脚本SQL 前段时间,在浏览javaeye论坛,看见有人征集如何在java中运行数学表达式.结果方案五花八门:1.jakarta commons JEXL. 2.Beanshell3.Java Math Expression Parser jep 4.parse combinator jparsec 5.jdk 6.0的 script6.利用SQL 7.自己写语法分析如果自己写语法分析,没有个200

在&lt;a&gt;&lt;/a&gt;标签中调用javascript脚本

有时候,我们点击了<a></a>标签(除了跳转到指定链接外)想要它调用某个方法,及调用javascript脚本,该如何做: 方法1:<a href="javascript:void(0);" onclick="functionname()" >aaaa</a> 方法2:<a href="javascript:functionname('dd')" >ddddd</a> 方法3

VC与JavaScript交互(三) ———— CWebPage类调用javascript函数(给js函数传参,并取得返回值)

①需要一个别人写好的类CWebPage,将其对于的两个文件WebPage.h和WebPage.cpp添加到工程中. ②添加WebBrowser控件,在视图/对话框类的头文件中#include "webbrowser2.h",增加成员变量m_webBrowser,调用Navigate()函数加载一个html页面. ③在对话框或者视图的实现文件中,加入#include "WebPage.h",在按钮的响应函数中就可以调用javascript函数了,具体代码如下: CWe

java中调用javascript

脚本语言的强大不用说,但是在java中怎么调用脚本语言呢? 灵活 便捷 简单 这些特性使脚本语言也让开发过程中变得不可缺少,于是java6开始正式支持脚本语言 但是由于脚本语言非常多,java的开发者也很难确定支持哪种语言,于是JCP(java Conmunity Process) 提出了JSR223规范,只要符合该规范的语言都可以在java平台上运行 如下给出一个java调用javascript的例子 function test(){obj,obj2}{ return obj1+obj2+nu

【Java记录】try-with-resources的一个坑

[Java记录]try-with-resources的一个坑 今天处理 AsynchronousFileChannel 时候的一个问题,代码如下: public static void main(String[] args) throws Exception { String filePath = "/home/xe/git/osc/JavaNote/Lang/data/Test.java"; ExecutorService executorService = Executors.ne