Marvin's Blog【程式人生】

Ability will never catch up with the demand for it

04 Nov 2020

基于Chromium的Edge WebView2

给Win32用的WebView2在10月份GA了。MS提供了WebView2 SDK可以供Win32 C/C++应用使用。相应的Windows Blog文章Announcing Microsoft Edge WebView2 General Availability

Getting started Win32

如果在一个Win32应用中使用WebView2。有用到Windows Implementation Library。宿主可以调用WebView2中的脚本函数。WebView2可以给宿主发消息。

Getting started WinUI3

至少需要Windows 10 1803 (build 17134)。以及Microsoft Edge (Chromium) Canary channel

WinUI目前只支持在WebView2 spec中提及的API。

  • WinUI 3 App
  • WinUI WebView element API
  • WebView2 Core API (尚未开放,CoreWebView2对象还不能直接使用)

Concepts Distribution of apps using WebView2

WebView2将有两个版本,一个是持续更新的Evergreen版,所有支持这个版本的App都会同享同一个App;另一个是断断续续的Fixed Version版(之前称为bring-your-own版),App需要自己打包runtime。

在应用启动前,必须保证WebView2的runtime已经安装。Microsoft Edge Stable channel不包含WebView2的runtime,只有在 (Beta/Dev/Canary)版本的Edge里面才包含。可以下载bootstrapper版本或者standalone版本的WebView2 runtime。

Concepts Managing the User Data Folder

WebVIew2需要一个目录来保存用户数据。可以显示指定一个目录(通过ICoreWebView2Environment的userDataFolder),也可以让WebView2自动创建。对于打包的应用商店程序,自动创建的目录在ApplicationData\LocalFolder;对于普通的exe程序,自动创建的目录.exe文件同目录,且名字是exe的文件名加上.WebView2。所以对于普通的exe程序,最好还是显示指定一个用户数据目录。

应用程序最好为每个用户创建不同的用户数据目录。对于每个用户的数据,可以选择在使用后保留,以便后续继续使用;或者不保留,每次重新创建。不同的WebView2实例可以共享同一个数据目录,但是有一些额外的注意事项。

Concepts Managing WebView2 applications

可以使用组策略对WebView2的Runtime进行一些控制:

Concepts Navigation events

当导航到一个页面时,会发生以下系列事件:

  • NavigationStarting,准备发送网络请求,在该事件中可以禁止这个请求。如果发生重定向,那么依然会停留在这个状态。这时候不会切换NavigationId,但是IsRedirect会变为true。
  • SourceChanged,准备切换到新URL。有些请求可以没有网络请求,而直接到这一步。比如fragment navigation。
  • HistoryChanged,历史记录更新
  • ContentLoading,开始加载目标页面
  • NavigationCompleted,导航完成。如果NavigationStarting失败的话,也会到这个状态。

每次导航到一个新的页面时会生成一个新的NavigationId,可以使用这个NavigationId来追踪。不同NavigationId的事件可能会交叉。比如,当开启一个NavigationStarting之后,可以开启另一个。第一NavigationStarting会跳到NavigationCompleted状态。第二个则会正常进行下去。

在子帧(subframe)中的话,只有FrameNavigationStarting和FrameNavigationCompleted两个事件。

Concepts Best practices for developing secure WebView2 applications

一些在使用WebView2时候的注意事项;

  • 要认识到web内容是不可靠的
    • 要对消息和参数进行验证,以防恶意篡改
    • 要对内容的来源进行检查,确保内容来源的可信度
  • 设计特有的web 消息以及跟host之间的交互,而不是使用通用的代理
  • 通过设置ICoreWebView2Settings的一些参数,达到对内容的严格控制
    • 将AreHostObjectsAllowed 设置为false,以避免web content访问host对象
    • 将IsWebMessageEnabled 设置为false,如果不需要web content给host发消息的话
    • 将IsScriptEnabled 设置为false,如果WebView2只是为了显示静态内容的话
    • 将AreDefaultScriptDialogsEnabled 设置为false,如果不喜欢web content显示alert或者prompt对话框

可以在NavigationStarting以及FrameNavigationStarting 中根据页面的来源设置不同的安全属性,甚至阻止页面跳到目标源。

当导航到一个新文档时,可以在ContentLoading事件中来移除默认暴露的host对象,对应的方法是RemoveHostObjectFromScript。

Concepts Process model

和Chrome一样,采用的是多进程模型。

Concepts Threading model

WebView2 控件必须运行在STA的COM之上。并且必须在UI线程创建。也就是带有消息循环(message pump)的队列。

CoreWebView2WebResourceRequest的Content下属是一个例外,它是从幕后线程加载的。

Concepts Versioning

想要使用WebView2,必须安装WebView2 Runtime,或者安装一个非稳定版的Microsoft Edge。关于版本,如果使用SDK package version 0.9.488,那么对应的WebView2 Runtime和非稳定版的Microsoft Edge的build number就必须是488或以上。在WebView2的发行注记Release Notes中会提到最小要求的版本。

WebView2 SDK包含发行版本以及预发行版本。前者包含Win32 C/C++ APIs,或者还包括.NET API(WPF,WinForms,Core)以及实验性质的API。

对于API的向后兼容性,Win32 C/C++可以使用QueryInterface来查询,如果返回E_NOINTERFACE,则表示不兼容。对于.NET和WinUI,则会抛出No such interface supported异常。

其他

(本篇完)

comments powered by Disqus