Qt嵌入浏览器(六)——QCefView实现JS通信接口

JavaScript07

Qt嵌入浏览器(六)——QCefView实现JS通信接口,第1张

上一节中,我们完成了CEF各基本组件的封装,并完成了浏览器基本功能的实现。 >>点这里回顾上节内容

本节我们将尝试扩展所实现的各组件,实现浏览器与页面的双向通信。

本篇的小目标:

上一节曾提到过,CEF应用在默认情况下包含很多子进程,这些进程会共享同一个执行入口。除了主进程的各类处理接口外,CEF还提供了各类子进程的处理接口。而 页面到浏览器的消息通道 就可以借助对 渲染进程 的控制来实现,整体流程如下:

完成上述步骤后,在页面调用对应的消息通道函数时,V8处理器则会相应地进行处理,从而完成消息的发送。

另一方面,实现 浏览器到页面 的消息通道和第二节中基于Qt WebEngine的方法类似,CEF也提供了执行JS脚本的方法,只需在页面中定义好对应的消息接口,并通过执行脚本方法执行该接口即可完成消息的发送。

因此,实现双向通道主要的问题集中在针对渲染进程处理和JS脚本执行的扩展上。接下来先就渲染进程处理进行说明。

为了实现对渲染进程的处理,我们首先需要向上一节中封装的QCefContext中添加对渲染进程入口的解析和处理。具体实现如下:

上面的实现除了处理了CEF主进程外,还判断了子进程是否为渲染进程(Windows环境下的renderer进程和Linux环境下的zygote进程),如果发现当前处理的是渲染进程,则创建一个渲染进程处理器QCefRenderHandler的实例。QCefRenderHandler的声明如下:

和主进程CefApp的实现类似,这里也实现了CefApp接口,此外额外实现了CefRenderProcessHandler接口的OnContextCreated方法,来获取V8上下文的引用,具体实现如下:

上面的实现将sendMessage函数定义为消息通道,并注册到了window对象上。sendMessage函数的具体实现则放在v8Handler的实现中。QCefV8Handler声明如下:

QCefV8Handler通过实现CEF V8处理器的Execute执行方法,完成对所加载的JS函数的过滤,并进行相应的处理,实现如下:

这里首先对函数名和参数进行了校验,之后调用CefBrowser的IPC方法SendProcessMessage向主进程的CefClient发送消息,从而完成页面向浏览器主进程消息的传递。

要实现页面到浏览器的消息通道,除了完成了上面渲染进程的控制扩展,我们还需要在QCefClient中添加接收IPC消息的接口实现。首先在QCefClient头文件中声明对CefClient接口的重载:

然后实现这个接口,完成消息的接收处理:

可以看到这里只是对收到的消息进行了简单的转换,并通过信号发送给感兴趣的下游控件使用。在第四小节的实现中,我们将QCefClient封装到了QCefView中,因此在QCefView中也需要将这个信号转发给它的下游控件:

这样,QCefView接收JS消息的通道就实现完成了。

这里额外讲解一下有关js alert的特殊处理。要实现js调用alert方法时的弹窗提醒,需要额外在CefClient中实现CefJSDialogHandler接口的OnJSDialog方法,参考实现如下:

承前所述,浏览器到页面的消息发送通过CEF的JS脚本执行接口实现。首先在QCefView中,声明并实现一个执行JS脚本的方法:

然后指定一个特定的JS方法,作为消息通道使用:

如此,QCefView发送JS的通道也实现完成了。

完成了消息通道的实现,接下来我们实际使用一下我们定义好的消息通道。

首先是Qt端的实现,在MainDlg的initWebView方法中,添加对JS消息的监听,并将监听到的消息通过QMessageBox显示出来:

然后添加文本输入和发送按钮,并在按钮点击信号对应的槽中调用QCefView的消息发送方法:

接下来在页面端实现消息接收和发送的接口msgutils.js:

可以看到这里我们使用了上面定义的recvMessage和sendMessage两个函数。然后在页面上调用这些接口:

实际运行一下浏览器,并加载我们实现的这个页面,消息发送效果如下:

有关CEF消息通道的讲解就先进行到这里。下一节将分析使用CEF接口实现Https双向认证的方法。

>>返回系列索引

[1] Chromium Embedded Framework官网

[2] Chromium Embedded Framework官方教程

Javascript是一种由Netscape的LiveScript发展而来的脚本语言.主要目的是为了解决服务器终端语言.比如Perl.遗留的速度问题.当时服务端需要对数据进行验证.由于网络速度相当缓慢.只有28.8kbps.验证步骤浪费的时间太多.于是Netscape的浏览器Navigator加入了Javascript.提供了数据验证的基本功能. 历史 在1992年.Nombas开始开发一种嵌入式脚本语言.叫做C-minus-minus(Cmm).[待续... 能够具有交互性.能够包含更多活跃的元素.就有必要在网页中嵌入其它的技术.如:Javascript.VBScript.Document Object Model(文件目标模块).Layers和 Cascading Style Sheets(CSS).这里主要讲Javascript.那么Javascript是什么东东?Javascript就是适应动态网页制作的需要而诞生的一种新的编程语言.如今越来越广泛地使用于Internet网页制作上. Javascript是由 Netscape公司开发的一种脚本语言(scripting language).或者称为描述语言.在HTML基础上.使用Javascript可以开发交互式Web网页.Javascript的出现使得网页和用户之间实现了一种实时性的.动态的.交互性的关系.使网页包含更多活跃的元素和更加精彩的内容. 运行用Javascript编写的程序需要能支持Javascript语言的浏览器.Netscape公司 Navigator 3.0以上版本的浏览器都能支持 Javascript程序.微软公司 Internet Explorer 3.0以上版本的浏览器基本上支持Javascript.微软公司还有自己开发的Javascript.称为JScript. Javascript和Jscript基本上是相同的.只是在一些细节上有出入. Javascript短小精悍. 又是在客户机上执行的.大大提高了网页的浏览速度和交互能力. 同时它又是专门为制作Web网页而量身定做的一种简单的编程语言. 虽然.在Dreamweaver的Behaviors可以为我们方便地使用Javascript程序而不用编写代码.但我们自己了解了Javascript的编程方法后.将能更加方便灵活地应用.也使Javascript的代码更简练.本专题通过对一系列典型程序的剖析.使你快速地掌握Javascript的编程技巧.设计出质量上乘的动态网页打下坚实的基础.在此之前.我们先了解一些Javascript 的基本概念. JavaScript 有什么特点 JavaScript 使网页增加互动性.JavaScript 使有规律地重复的HTML文段简化.减少下载时间.JavaScript 能及时响应用户的操作.对提交表单做即时的检查.无需浪费时间交由 CGI 验证.JavaScript 的特点是无穷无尽的.只要你有创意. Java 与 JavaScript 有什么不同 很多人看到 Java 和 JavaScript 都有[Java"四个字.就以为它们是同一样东西.连我自己当初也是这样.其实它们是完完全全不同的两种东西.Java.全称应该是 Java Applet.是嵌在网页中.而又有自己独立的运行窗口的小程序.Java Applet 是预先编译好的.一个 Applet 文件(.class)用 Notepad 打开阅读.根本不能理解.Java Applet 的功能很强大.可以访问 http.ftp等协议.甚至可以在电脑上种病毒(已有先例了).相比之下.JavaScript 的能力就比较小了.JavaScript 是一种[脚本"([Script").它直接把代码写到 HTML 文档中.浏览器读取它们的时候才进行编译.执行.所以能查看 HTML 源文件就能查看JavaScript 源代码.JavaScript 没有独立的运行窗口.浏览器当前窗口就是它的运行窗口.它们的相同点.我想只有同是以 Java 作编程语言一点了. 开发JavaScript 该用什么软件 一个JavaScript 程序其实是一个文档.一个文本文件.它是嵌入到 HTML 文档中的.所以.任何可以编写 HTML 文档的软件都可以用来开发 JavaScript.在此我推荐大家用 FrontPage 2000 附带的 Microsoft 脚本编辑器(在 FrontPage 菜单 | 工具 | 宏 | Microsoft 脚本编辑器).它是个像 Visual Basic / C++ 一样的程序开发器.能对正在输入的语句作出简要提示.配合 FrontPage 2000.使工作量大大减少. 一.Javascript在网页的用法 Javascript加入网页有两种方法: 1.直接加入HTML文档 这是最常用的方法.大部分含有Javascript的网页都采用这种方法.如: <script language="Javascript"> <!-- document.writeln("这是Javascript!采用直接插入的方法!"), //-Javascript结束--> </script> 在这个例子中.我们可看到一个新的标签: <script>--</script>.而<script language="Javascript"> 用来告诉浏览器这是用Javascript编写的程序.需要调动相应的解释程序进行解释. HTML的注释标签<!--和-->:用来去掉浏览器所不能识别的Javascript源代码的.这对不支持 Javascript 语言的浏览器来说是很有用的. //-Javascript结束:双斜杠表示 Javascript的注释部分.即从//开始到行尾的字符都被忽略. 至于程序中所用到的document.write()函数则表示将括号中的文字输出到窗口中去. 这在后面将会详细介绍. 另外一点需要注意的是.<script>--</script>的位置并不是固定的.可以包含在<head>......</head> 或<body>.....</body>中的任何地方. 2.引用方式 如果已经存在一个Javascript源文件(以js为扩展名).则可以采用这种引用的方式.以提高程序代码的利用率.其基本格式如下: <script src=url language="Javascript"></script> 其中的Url就是程序文件的地址.同样的.这样的语句可以放在HTML文档头部或主体的任何部分. 如果要实现[直接插入方式"中所举例子的效果.可以首先创建一个Javascript源代码文件[Script.js".其内容如下: document.writeln("这是Javascript!采用直接插入的方法!"), 在网页中可以这样调用程序:<script src="Script.js" language="Javascript"></script> . 二.Javascript基本概念 在这里只作简单介绍.在以后的例子中结程序再作具体解释其作用. 1.运算符 运算符就是完成操和的一系列符号.它有七类: 赋值运算符.算术运算符.比较运算符.逻辑运算符.条件运算.位操作运算符和字符串运算符. 2.表达式 运算符和操作数的组合称为表达式.通常分为四类:赋值表达式.算术表达式.布尔表达式和字符串表达式. 3.语句 Javascript程序是由若干语句组成的.语句是编写程序的指令.Javascript提供了完整的基本编程语句.它们是: 赋值语句.switch选择语句.while循环语句.for循环语句.do while循环语句.break循环中止语句和continue循环中断语句. 4.函数 函数是命名的语句段.这个语句段可以被当作一个整体来引用不着和执行.使用函数要注意以下几点: 1)函数由关键字function定义, 2)函数必须先定义后使用.否则将出错, 3)函数名是调用函数时引用的名称.它对大小写是敏感的.调用函数时不可写错函数名, 4)参数表示传递给函数使用或操作的值.它可以是常量.也可以是变量, 5)return语句用于返回表达式的值.也可以没有. 5.对象 Javascript的一个重要功能就是基于对象的功能.通过基于对象的程序设计.可以用更直观.模块化和可重复使用的方式进行程序开发. 一组包含数据的属性和对属性中包含数据进行操作的方法.称为对象.比如要设定网页的背景颜色.所针对的对象就是document.所用的属性名是bgcolor.如document.bgcolor="blue".就是表示使背景的颜色为蓝色. 6.事件 用户与网页交互时产生的操作.称为事件.绝大部分事都由用户的动作所引发.如:用户按鼠标的按钮.就产生onclick事件.若鼠标的指针的链接上移动.就产生onmouseover事件等等.在Javascript中.事件往往与事件处理程序配套使用. 学习Javascript比较快速有效的方法是先熟悉一些基本概念.然后找几个别人设计好的程序认真仔细地分析一遍.再稍作改动.再看看能否达到预期目的.不断地举一反三.既可以加深对一些参数.设计方法的理解.又可以快速地提高自己的水平.另外.再提醒一下:Javascript对大小写是敏感的.特别是一些对象.方法.属性的大小写一定要一致.要养成一种良好的习惯.否则在调试程序时可要累死你了. 7.变量 如var myVariable = "some value",