在我们深入研究博文的细节之前,提供一些关于我们正在努力实现的目标的背景会很有帮助,同意吗?我一直在研究需要在 WebView 控件中显示/包含一些移动应用程序的混合移动应用程序。在后台需要经过一些Http请求来收集数据,做进一步的处理。我们需要在所有通过移动应用程序的 Web 请求中保持相同的会话。这意味着 Webview 发起的所有 Web (http) 请求以及我们的后台 (httpClient) 请求都需要共享 cookie、缓存等。那么我们该怎么做呢?这就是我将在这篇博文中向您展示的内容。
系统.Net.Http.HttpClient
HttpClient 已经成为所有 Http 的首选库,特别是在 PCL(可移植类库)中的 HttpClient 支持下,谁能抗拒。因此,当我考虑此要求时,我的第一个想法是将 HttpClient 与 HttpClientHandler 一起使用,保留会话 cookie 并将它们与 WebView 共享。我开始了我最初的谷歌搜索,我发现有人已经这样做了,你可以 在这里 找到它。这让我更有信心它是可行的并且对某些人有用,所以这是我可以采用的第一种方法。
第一种方法意味着使用 HttpClient(连同 HttpClientHandler)来保存 cookie 并与 webview 共享它们。但是,这很容易出错,因为我需要持续监控这两个 cookie 并更新另一组请求。另外,在 WebView 和 HttpClient 之间共享数据缓存仍然是一个我不确定如何解决的问题。
Windows.Web.HttpClient
在继续之前,我想我会寻找替代方案,然后我找到了 Windows.Web.HttpClient 。这看起来与 System.Net.Http.HttpClient 非常相似,但实现方式却大不相同,无论名称是否完全匹配:)。我从 Microsoft //Build confernece 找到了这个视频(下方),它详细讨论了 HttpClient 的实现,正如名称所示,它更适合 Windows 开发。
显然,HttpClient 的 Windows 实现使您能够自定义 http 请求的所有方面。上面的视频列出了您应该使用 Windows.Web.HttpClient 的以下五个原因:
- 共享 Cookie、缓存和 Credentails(我认为这好得令人难以置信)
- 强类型标头 => 更少的错误
- 访问 Cookie 和共享 Cookie
- 控制缓存和 Sahred 缓存
- 将您的代码模块注入处理管道 => 更清晰的集成
当我读到上面的第一条陈述时,我真的觉得这太好了,难以置信,这正是我正在寻找的。所以我决定试一试。如您所见,为这个 HttpClient(Windows 实现)列出的一些功能与我们在 System.Net 世界中拥有的功能相似,但这为我们提供了额外的功能。
HttpClientHandlers 与 HttpBaseProtocolFilter
值得一提的是,Windows.Web 库中并没有我们熟悉的 System.Net 中的 HttpClientHandlers,而是提供了使用 HttpBaseProtocolFilter 做更多事情的能力,这是重点。 HttpBaseProtocolFilter 使我们的开发人员能够自定义/操作 http 请求(标头、cookie、缓存等),并且更改将全面应用于您的应用程序。无论您是使用 httpClient 还是通过用户界面(例如使用 webView)以编程方式发出 http 请求,这都适用。
代码时间
// creating the filter
var myFilter = new HttpBaseProtocolFilter();
myFilter.AllowAutoRedirect = true;
myFilter.CacheControl.ReadBehavior = HttpCacheReadBehavior.Default;
myFilter.CacheControl.WriteBehavior = HttpCacheWriteBehavior.Default;
// get a reference to the cookieManager (this applies to all requests)
var cookieManager = myFilter.CookieManager;
// make the httpRequest
using (var client = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "your-url-address");
// add any request-specific headers here
// more code been omitted
var result = await client.SendRequstAsync(request);
result.EnsureSuccessStatusCode();
var content = await result.Content.ReadAsStringAsync();
// now we can do whatever we need with the html content we got here
// Debug.WriteLine(content);
}
// assuming that the previous request created a session (set cookies, cached some data, etc)
// subsequent requests in the webview will share this data
myWebView.Navigate(new Uri("your-url-address"));
希望这个简短的代码片段能让您很好地了解可以使用 HttpClient 的 Windows 实现做什么。
其他应用?
有人可能会问这将如何影响其他应用程序?答案是不会。正如您将在视频中看到的那样(如果您看过它:)),Windows.Web 库旨在处理 一个应用程序中的 所有请求。因此,您无需担心影响其他应用程序或将您的数据泄露给其他外部请求。
结论
一位 智者曾经说过“能力越大,责任越大”。在您的 http 请求中使用 HttpBaseProtocolFilter 时应记住这一点,因为这会影响您的所有后续请求。希望您觉得这很有用,并希望听到您的意见和反馈。