在升级 ASP.NET Core Blazor 应用时避免 HTTP 缓存问题

注意

此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本

重要

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。

对于当前版本,请参阅此文的 .NET 8 版本

如果 Blazor 应用升级或配置不正确,可能会导致现有用户进行非无缝升级。 本文讨论跨主版本升级 Blazor 应用时可能发生的一些常见 HTTP 缓存问题。 它还提供一些建议的操作,来确保用户顺利过渡。

虽然未来的 Blazor 版本可能会提供更好的解决方案来处理 HTTP 缓存问题,但最终取决于应用是否正确配置缓存。 适当的缓存配置可确保应用的用户始终拥有应用的最新版本,从而改善他们的体验并减少遇到错误的可能性。

对用户升级体验产生负面影响的常见问题包括:

  • 对项目和包更新的处理不正确:如果没有将应用所有已部署的项目都更新为使用同一主框架版本,或者在更新的版本作为主要升级的一部分提供时使用更低版本中的包,则会发生此情况。
  • 缓存标头的配置不正确:HTTP 缓存标头可控制应用响应的缓存方式、位置和时长。 如果标头配置不正确,用户可能会收到过时的内容。
  • 其他层的配置不正确:如果配置不正确,内容分发网络 (CDN) 和已部署应用的其他层可能会导致问题。 例如,CDN 被设计为缓存和传送内容以提高性能并减少延迟。 如果 CDN 未正确提供资产的缓存版本,可能会导致向用户交付过时的内容。

检测和诊断升级问题

升级问题通常表现为无法在浏览器中启动应用。 通常,警告指示存在过时的资产,或者资产缺失或与应用不一致。

  • 首先,检查应用是否在干净浏览器实例中成功加载。 使用专用浏览器模式加载应用,例如 Microsoft Edge InPrivate 模式或 Google Chrome 无痕模式。 如果应用加载失败,可能意味着一个或多个包或框架未正确更新。
  • 如果应用在干净的浏览器实例中正确加载,则应用可能是从过时的缓存中提供的。 在大多数情况下,使用 Ctrl+F5 进行浏览器硬刷新会刷新缓存,从而使得应用能够使用最新资产加载和运行。
  • 如果应用仍然失败,则可能是过时的 CDN 缓存正在为应用提供服务。 请尝试通过 CDN 提供商提供的机制刷新 DNS 缓存。

先前为应用提供服务的过程可能会使更新过程更具挑战性。 例如,过去避免或错误地使用缓存标头可能会导致用户当前出现缓存问题。 可采取以下部分中的操作来缓解问题并改进用户的升级过程。

使框架包与框架版本保持一致

确保框架包与框架版本一致。 如果有更新的版本可用,却使用更低版本中的包,可能会导致兼容性问题。 此外,请务必确保应用已部署的所有项目都使用相同的主框架版本。 这种一致性有助于避免出现意外的行为和错误。

验证是否存在正确的缓存标头

对资源请求的响应中应存在正确的缓存标头。 这包括 ETagCache-Control 和和其他缓存标头。 这些标头的配置依赖于托管服务或托管服务器平台。 它们对于 Blazor 脚本 (blazor.webassembly.js) 和脚本下载的任何内容等资产尤其重要。

HTTP 缓存标头不正确也可能会影响服务辅助角色。 服务辅助角色依赖于缓存标头来有效地管理缓存的资源。 因此,标头不正确或缺失可能会中断服务辅助角色的功能。

使用 Clear-Site-Data 在浏览器中删除状态

请考虑使用 Clear-Site-Data 标头 在浏览器中删除状态。

通常,缓存状态问题的来源仅限于 HTTP 浏览器缓存,因此使用 cache 指令应该就足够了。 此操作有助于确保浏览器从服务器提取最新资源,而不是从缓存中提供过时的内容。

可选择性地包含 storage 指令,以在清除 HTTP 浏览器缓存的同时清除本地存储缓存。 但是,如果使用 storage 指令,使用客户端存储的应用可能会丢失重要信息。

将查询字符串追加到 Blazor 脚本标记

如果上面建议的操作都无效、无法用于部署或无法运用于应用,请考虑暂时将查询字符串追加到 Blazor 脚本的 <script> 标记源。 在大多数情况下,此操作应该足以强制浏览器绕过本地 HTTP 缓存并下载新版本的应用。 无需在应用中读取或使用查询字符串。

在以下示例中,查询字符串 temporaryQueryString=1 暂时应用于 <script> 标记的相对外部源 URI:

<script src="_framework/blazor.webassembly.js?temporaryQueryString=1"></script>

在应用的所有用户重新加载应用后,可以移除查询字符串。

或者,可以应用具有相关版本控制的持久查询字符串。 以下示例假定应用版本与 .NET 版本匹配(对于 .NET 8,为 8):

<script src="_framework/blazor.webassembly.js?version=8"></script>

有关 Blazor 脚本的 <script> 标记的位置,请参阅 ASP.NET Core Blazor 项目结构