【发布时间】:2012-10-18 15:10:42
【问题描述】:
我有一个 MVC .Net 应用程序,它具有返回报告文件的操作,通常是.xslx:
byte[] data = GetReport();
return File(data,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"filename.xlsx");
这在测试和所有浏览器中都非常有效,但是当我们将它放在 SSL 站点上时,它在 IE6、7 和 8(所有合适的浏览器仍然可以正常工作)上失败,并出现这个无益的错误:
这曾经在此操作所取代的遗留应用程序(非 MVC)中工作。
我们不能告诉我们的用户在本地进行任何更改 - 大约 60% 的用户仍在使用 IE6!
如何使用 MVC 解决此问题?
更新
进一步挖掘表明这是 IE6-8 中的根本故障。根据Eric Law's IE internals blog,这是因为在 SSL 连接期间,IE 将 no-cache 指令视为绝对规则。因此,与其不缓存副本,它认为 no-cache 意味着即使在以下情况下也不应该将副本保存到磁盘
Content-Disposition:attachment 并明确提示下载位置。
显然这是错误的,但是虽然它在 IE9 中得到了修复,但我们仍然坚持所有 IE6-8 用户。
使用 MVC 的动作过滤器属性会产生以下标题:
Cache-Control:no-cache, no-store, must-revalidate
Pragma:no-cache
使用 Fiddler 动态更改这些,我们可以验证需要返回的标头:
Cache-Control:no-store, no-cache, must-revalidate
注意Cache-Control的顺序必须有no-store之前no-cache并且Pragma指令必须是完全删除。
这是一个问题——我们广泛使用 MVC 的动作属性,我真的不想从头开始重写它们。即使我们可以在您尝试删除 Pragma 指令时 IIS 抛出异常。
如何让微软的MVC和IIS返回微软的IE6-8在HTTPS下可以处理的no-cache指令?我不想允许对响应进行私有缓存(根据 similar question)或忽略带有覆盖的 MVC 内置方法(根据我自己的答案,这只是我目前最好的 hack)。
【问题讨论】:
-
@tpeczek 查看更新 - 如果可能的话,我不打算覆盖 MVC 的操作过滤器,但我会检查答案。
-
@tpeczek 这个问题的答案似乎是使用
Cache-Control:private,这意味着如果用户在同一个会话中下载同一个文件两次,他们将从他们的本地浏览器缓存而不是最新数据。这不是一个修复。我需要告诉浏览器不要以 IE 可以理解的格式缓存(但允许下载) -
让我们明确一下这个问题 - 我想知道如何让 MVC 输出 IE6-8 理解的缓存指令,不是使缓存私有可以有一个类似的效果。我有类似的症状,但Calin's question 对我没用。
标签: asp.net-mvc internet-explorer https mime-types