gpt4 book ai didi

ASP.NET MVC 和 IE 缓存 - 操作响应 header 无效

转载 作者:行者123 更新时间:2023-12-03 11:01:52 25 4
gpt4 key购买 nike

背景

我正在尝试帮助一位同事调试过去 6 个月内没有出现的问题。在最近一次部署 ASP.NET MVC 2 应用程序后,FileResult强制用户打开或保存 PDF 文件的响应在客户端计算机上存在足够长的时间以供 PDF 阅读器打开它们时遇到问题。

IE 的早期版本(尤其是 6)是唯一受影响的浏览器。 Firefox 和 Chrome 以及更新版本的 IE (>8) 都按预期运行。考虑到这一点,下一部分定义了重新创建问题所需的操作。

行为

  • 用户单击指向操作方法的链接(带有 href 属性的普通超链接)。
  • action 方法生成一个表示为字节流的 PDF。该方法总是重新创建 PDF。
  • 在 action 方法中,设置 header 以指示浏览器如何缓存响应。他们是:
    response.AddHeader("Cache-Control", "public, must-revalidate, post-check=0, pre-check=0");
    response.AddHeader("Pragma", "no-cache");
    response.AddHeader("Expires", "0");

    对于那些不熟悉 headers 的人做:

    一种。 缓存控制:公共(public)

    Indicates that the response MAY be cached by any cache, even if it would normally be non-cacheable or cacheable only within a non- shared cache.



    湾。 缓存控制:必须重新验证

    When the must-revalidate directive is present in a response received by a cache, that cache MUST NOT use the entry after it becomes stale to respond to a subsequent request without first revalidating it with the origin server



    C。 缓存控制:预检查 (在 IE5 中引入)

    Defines an interval in seconds after which an entity must be checked for freshness. The check may happen after the user is shown the resource but ensures that on the next roundtrip the cached copy will be up-to-date.



    d。 缓存控制:检查后 (在 IE5 中引入)

    Defines an interval in seconds after which an entity must be checked for freshness prior to showing the user the resource.



    e. 编译指示:无缓存 (确保向后兼容 HTTP/1.0)

    When the no-cache directive is present in a request message, an application SHOULD forward the request toward the origin server even if it has a cached copy of what is being requested



    F。 过期

    The Expires entity-header field gives the date/time after which the response is considered stale.

  • 我们从 Action 中返回文件
    return File(file, "mime/type", fileName);
  • 用户会看到一个打开/保存对话框
  • 单击“保存”按预期工作,但单击“打开”会启动 PDF 阅读器,但存储的临时文件 IE 在阅读器尝试打开文件时已被删除,因此它提示文件丢失(并且它是)。

  • 这里有六个其他应用程序使用相同的标题来强制 Excel、CSV、PDF、Word 和大量其他内容向用户发送,并且从来没有出现过问题。

    问题
  • 标题是否适合我们正在尝试做的事情?我们希望文件暂时存在(被缓存),但总是被新版本替换,即使请求可能相同)。

  • 在返回 FileResult 之前,在 action 方法中设置了响应 header 。 .我已经让我的同事尝试创建一个继承自 FileResult 的新类。而是覆盖 ExecuteResult方法,以便它修改标题,然后执行 base.ExecuteResult()相反 - 没有状态。

    我有一种预感,“0”的“Expires”标题是罪魁祸首。根据 this W3C article ,将其设置为“0”意味着“已经过期”。我确实希望它过期,我只是不希望 IE 在处理它的应用程序有机会打开它之前将其从文件系统中删除。

    一如既往,谢谢!

    编辑:解决方案

    经过进一步测试(使用 Fiddler 检查 header ),我们看到我们认为设置的响应 header 不是浏览器正在解释的 header 。由于我自己不熟悉代码,我没有意识到一个潜在的问题:标题在操作方法之外被踩到了。

    尽管如此,我将保留这个问题。仍然很突出的是: Expires 之间似乎存在一些差异。值为 0 的 header 与 -1 .如果有人可以通过设计声称差异,关于 IE,我仍然想听听。至于解决方案,上述 header 确实可以按 Expires 的预期工作。值设置为 -1在所有浏览器中。

    更新 1

    帖子 How to control web page caching, across all browsers?详细描述了通过设置 Expires = 0 可以在所有浏览器中防止缓存。我仍然不相信这个 0对比 -1争论...

    最佳答案

    我认为你应该只使用

    HttpContext.Current.Response.Cache.SetMaxAge (new TimeSpan (0));

    或者
    HttpContext.Current.Response.Headers.Set ("Cache-Control", "private, max-age=0");

    设置 max-age=0 这意味着缓存重新验证(参见 here )。如果您将在 header 中另外设置 ETag 以及数据中的一些自定义哈希校验和,则来自上一个请求的 ETag 将被发送到服务器。服务器可以返回数据,或者如果数据与以前完全相同,它可以返回空正文和 HttpStatusCode.NotModified 作为状态码。在这种情况下,Web 浏览器将从本地浏览器缓存中获取数据。

    我建议您使用 Cache-Control: private 强制执行两件重要的事情:1)关闭代理上的缓存数据,该代理有时具有非常激进的缓存设置 2)它将允许缓存数据,但不允许与另一个用户。它可以解决隐私问题,因为您返回给一个用户的数据可能不允许其他用户读取。顺便说一句,默认情况下,代码 HttpContext.Current.Response.Cache.SetMaxAge (new TimeSpan (0)) 在 HTTP header 中设置为 Cache-Control: private, max-age=0。如果您确实想使用 Cache-Control: public ,您可以使用 SetCacheability (HttpCacheability.Public); 覆盖行为或使用 Headers.Set 而不是 Cache.SetMaxAge

    如果您有兴趣研究更多 HTTP 协议(protocol)的缓存选项,我建议您阅读 caching tutorial

    更新 :我决定写更多信息来清除我的位置。对应于来自维基百科的 the information 即使像 Mosaic 2.7、Netscape 2.0 和 Internet Explorer 3.0 这样的旧网络浏览器支持 1996 年 3 月,RFC 2068 中描述的 HTTP/1.1 的预标准。所以我想(但不测试)旧网络浏览器支持 max-age=0 HTTP header 。无论如何,Netscape 2.06 和 Internet Explorer 4.0 都明确支持 HTTP 1.1。

    所以你应该首先问你:你使用哪些 HTML 标准?您是否仍然使用 HTML 2.0 而不是 1997 年 1 月发布的更晚的 HTML 3.2?我想您至少使用 1997 年 12 月发布的 HTML 4.0。因此,如果您至少在 HTML 4.0 中构建应用程序,您的站点可以面向支持 HTTP 1.1 的 Web 客户端,而忽略(不支持)支持 HTTP 1.1 的 Web 客户端不支持 HTTP 1.1。

    现在将其他“Cache-Control” header 称为“private,max-age = 0”。在我看来,包括标题是 纯偏执狂 。由于我自己有一些缓存问题,我也尝试包含不同的其他 header ,但后来在仔细阅读了 RFC2616 的第 14.9 节后,我只使用了“Cache-Control: private, max-age=0”。

    唯一可以额外讨论的“Cache-Control” header 是我之前引用的第 14.9.4 节中描述的“must-revalidate”。这是报价:

    The must-revalidate directive is necessary to support reliable operation for certain protocol features. In all circumstances an HTTP/1.1 cache MUST obey the must-revalidate directive; in particular, if the cache cannot reach the origin server for any reason, it MUST generate a 504 (Gateway Timeout) response.

    Servers SHOULD send the must-revalidate directive if and only if failure to revalidate a request on the entity could result in incorrect operation, such as a silently unexecuted financial transaction. Recipients MUST NOT take any automated action that violates this directive, and MUST NOT automatically provide an unvalidated copy of the entity if revalidation fails.

    Although this is not recommended, user agents operating under severe connectivity constraints MAY violate this directive but, if so, MUST explicitly warn the user that an unvalidated response has been provided. The warning MUST be provided on each unvalidated access, and SHOULD require explicit user confirmation.



    有时,如果我遇到 Internet 连接问题,我会看到带有“网关超时”消息的空白页面。它来自“必须重新验证”指令的使用。我不认为“网关超时”消息真的对用户有帮助。

    因此,如果他在调用老板时听到“忙”信号,如何更愿意启动自毁程序,应该在“缓存控制”标题中另外使用“必须重新验证”指令。我建议其他人只使用“Cache-Control: private, max-age=0”,仅此而已。

    关于ASP.NET MVC 和 IE 缓存 - 操作响应 header 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9234044/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com