我有一个 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 的 IE 内部博客,这是因为在 SSL 连接期间,IE 将 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
must have no-store
before的顺序,并且 必须完全删除no-cache
该Pragma
指令。
这是一个问题——我们广泛使用 MVC 的动作属性,我真的不想从头开始重写它们。即使我们可以在您尝试删除Pragma
指令时 IIS 抛出异常。
如何让微软的 MVC 和 IIS 返回微软的 IE6-8 在 HTTPS 下可以处理的 no-cache 指令?我不想允许私有缓存响应(根据这个类似的问题)或忽略带有覆盖的 MVC 内置方法(根据我自己的答案,这只是我目前最好的 hack)。