我有一个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指令视为绝对规则。因此,与其说不缓存副本,不如说它不缓存意味着即使在以下情况下也无法将副本保存到磁盘上:Content-Disposition:attachment并带有明确提示,提示您下载位置。

显然这是错误的,但是尽管它在IE9中已得到修复,但我们仍然对所有IE6-8用户保持不变。

使用MVC的 Action 过滤器属性会生成以下 header :
Cache-Control:no-cache, no-store, must-revalidate
Pragma:no-cache

使用Fiddler即时更改这些内容,我们可以验证需要返回的 header :
Cache-Control:no-store, no-cache, must-revalidate

请注意,Cache-Control 的顺序必须no-store之前具有no-cache,并且Pragma指令必须必须完全删除

这是一个问题-我们广泛使用MVC的 Action 属性,我真的不想从头开始重写它们。即使我们尝试删除Pragma指令,IIS也会引发异常。

您如何使Microsoft的MVC和IIS返回Microsoft的IE6-8在HTTPS下可以处理的no-cache指令?我不想允许响应的私有(private)缓存(按照similar question的要求)或忽略带有覆盖的MVC内置方法(按照我自己的答案,这只是我目前的最佳技巧)。

最佳答案

我想出了一种解决方法,但这是一个明确的技巧-这是一个新的缓存属性,用于替换内置的[OutputCache]:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class IENoCacheAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsSecureConnection &&
            string.Equals(filterContext.HttpContext.Request.Browser.Browser, "IE", StringComparison.OrdinalIgnoreCase) &&
            filterContext.HttpContext.Request.Browser.MajorVersion < 9)
        {
            filterContext.HttpContext.Response.ClearHeaders();
            filterContext.HttpContext.Response.AddHeader("cache-control", "no-store, no-cache, must-revalidate");
        }
        else
        {
            filterContext.HttpContext.Response.Cache.SetNoStore();
            filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        }

        base.OnResultExecuting(filterContext);
    }
}

不过,这只是一个解决方法-我真正想要的是扩展现有的[OutputCache]Response.Cache结构,以便它们具有适合旧版IE的所需输出。

关于asp.net-mvc - IE6-8无法从HTTPS站点下载文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13119340/

10-12 12:43
查看更多