在 Windows Phone 上的 HttpClient 和 WebViews 之间共享会话

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

在我们深入研究博文的细节之前,提供一些关于我们正在努力实现的目标的背景会很有帮助,同意吗?我一直在研究需要在 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 的以下五个原因:

  1. 共享 Cookie、缓存和 Credentails(我认为这好得令人难以置信)
  2. 强类型标头 => 更少的错误
  3. 访问 Cookie 和共享 Cookie
  4. 控制缓存和 Sahred 缓存
  5. 将您的代码模块注入处理管道 => 更清晰的集成

当我读到上面的第一条陈述时,我真的觉得这太好了,难以置信,这正是我正在寻找的。所以我决定试一试。如您所见,为这个 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 时应记住这一点,因为这会影响您的所有后续请求。希望您觉得这很有用,并希望听到您的意见和反馈。