从 2.4 迁移到 2.5
在 DotNetBrowser 2.5 中,Chromium 引擎已升级到 88 版本。 这个 Chromium 版本在源代码中有一些破坏性的更改,影响了产品的公共 API。 在本迁移指南中,我们将介绍 2.5 中已删除/更改的 API,以及应该使用的替代方案。
已删除的 API
Flash 支持
Chromium 88 不再支持 Flash,因此以下引擎选项已过时,并从 API 中删除:
EngineOptions.PpapiFlashPath
EngineOptions.PpapiFlashVersion
UI 语言
以下 UI 语言已被移除,因为它们不再得到 Chromium 的官方支持:
- 南非语
- 中文(香港)
- 法语(加拿大)
- 英语(澳大利亚)
- 祖鲁语
添加或更新的 API
网络
拦截请求
v2.4
为了拦截标准的 URL 请求(例如 http
、https
)和自定义协议(例如 my-app
),使用了 InterceptRequestHandler
。 它允许拦截请求并覆盖响应数据,就好像这些数据是从网络服务器发送的一样。
下面介绍如何在 2.4 中使用 myscheme
方案拦截请求:
engine.Network.InterceptRequestHandler =
new Handler<InterceptRequestParameters, InterceptRequestResponse>(p =>
{
if(!p.UrlRequest.Url.StartsWith("myscheme"))
{
return InterceptRequestResponse.Proceed();
}
UrlRequestJobOptions options = new UrlRequestJobOptions
{
Headers = new List<HttpHeader>
{
new HttpHeader("Content-Type", "text/html", "charset=utf-8"),
}
};
UrlRequestJob job = p.Network.CreateUrlRequestJob(p.UrlRequest, options);
Task.Run(() =>
{
// 请求处理在后台线程中进行
// 以避免冻结网页。
job.Write(Encoding.UTF8.GetBytes("My data"));
job.Complete();
});
return InterceptRequestResponse.Intercept(job);
});
...
browser.Navigation.LoadUrl("myscheme://app/hello");
engine.Network.InterceptRequestHandler =
New Handler(Of InterceptRequestParameters, InterceptRequestResponse)(Function(p)
If Not p.UrlRequest.Url.StartsWith("myscheme") Then
Return InterceptRequestResponse.Proceed()
End If
Dim options As New UrlRequestJobOptions With {
.Headers = New List(Of HttpHeader) From {
New HttpHeader("Content-Type", "text/html", "charset=utf-8")}
}
Dim job As UrlRequestJob = p.Network.CreateUrlRequestJob(p.UrlRequest, options)
Task.Run(Sub()
' 请求处理在后台线程中进行
' 以避免冻结网页。
job.Write(Encoding.UTF8.GetBytes("My data"))
job.Complete()
End Sub)
Return InterceptRequestResponse.Intercept(job)
End Function)
'...
browser.Navigation.LoadUrl("myscheme://app/hello")
v2.5
以前拦截所有请求的方法存在一些安全限制和问题:
- 被拦截的自定义方案被视为非标准方案,因此您无法拦截自定义方案并返回包含访问
LocalStorage
的 JavaScript 的 HTML。 这将导致拒绝访问错误; - 并非所有方案都可以被拦截。 例如,禁止拦截
chrome
、data
或chrome-extensions
等方案。 上一版本的 API 允许这样做,这可能会导致在 Chromium 中出现意外行为或崩溃; - 某些方案被视为本地方案,如
file
。 它们无法被拦截,因为它不是网络请求。
在此版本中,我们改进了API,允许拦截 URL 请求和注册自定义方案。 新版本中没有上述安全限制和问题。
下面的示例演示了如何注册自定义 myscheme
方案并拦截所有相应的 URL 请求:
var handler = new Handler<InterceptRequestParameters, InterceptRequestResponse>(p =>
{
UrlRequestJobOptions options = new UrlRequestJobOptions
{
Headers = new List<HttpHeader>
{
new HttpHeader("Content-Type", "text/html", "charset=utf-8"),
}
};
UrlRequestJob job = p.Network.CreateUrlRequestJob(p.UrlRequest, options);
Task.Run(() =>
{
// 请求处理在后台线程中执行
// 以避免冻结网页。
job.Write(Encoding.UTF8.GetBytes("My data"));
job.Complete();
});
return InterceptRequestResponse.Intercept(job);
});
IEngine engine = EngineFactory.Create(new EngineOptions.Builder
{
Schemes =
{
{ Scheme.Create("myscheme"), handler }
}
}.Build());
IBrowser browser = engine.CreateBrowser();
browser.Navigation.LoadUrl("myscheme://app/hello");
Dim handler As New Handler(
Of InterceptRequestParameters, InterceptRequestResponse)(Function(p)
Dim options As New UrlRequestJobOptions With {
.Headers = New List(Of HttpHeader) From {
New HttpHeader("Content-Type", "text/html", "charset=utf-8")}
}
Dim job As UrlRequestJob = p.Network.CreateUrlRequestJob(p.UrlRequest, options)
Task.Run(Sub()
' 请求处理在后台线程中执行
' 以避免冻结网页。
job.Write(Encoding.UTF8.GetBytes("My data"))
job.Complete()
End Sub)
Return InterceptRequestResponse.Intercept(job)
End Function)
Dim engine As IEngine = EngineFactory.Create(New EngineOptions.Builder With {
.Schemes = {
{ Scheme.Create("myscheme"), handler }
}
}.Build())
Dim browser As IBrowser = engine.CreateBrowser()
browser.Navigation.LoadUrl("myscheme://app/hello")
如果无法拦截指定的方案, EngineOptions
构建器将抛出相应的异常。 例如:” “file” 方案无法被拦截。”
已知限制
在 Chromium 88 中,安全限制变得更加严格。 因此,当使用 LoadHtml
加载依赖于外部脚本的 HTML 文档时,它永远不会加载这些脚本,并记录错误信息 Failed to load resource: net::ERR_NOT_IMPLEMENTED
。
可能的解决方法是使用 data:
编码 URI,然后使用常规的 LoadUrl 调用加载它。 下面是一个例子:
var html = "<html><head></head><body><h1>Html Encoded in URL!</h1></body></html>";
var base64EncodedHtml = Convert.ToBase64String(Encoding.UTF8.GetBytes(html));
browser.Navigation.LoadUrl("data:text/html;base64," + base64EncodedHtml).Wait();
Dim html = "<html><head></head><body><h1>Html Encoded in URL!</h1></body></html>"
Dim base64EncodedHtml = Convert.ToBase64String(Encoding.UTF8.GetBytes(html))
browser.Navigation.LoadUrl("data:text/html;base64," & base64EncodedHtml).Wait()
不过,使用这种解决方法时无法设置基本 URL。
另一种可行的方法是向处理程序注册 Scheme
,并拦截相应的请求以提供 HTML。 请参阅相应的文章。