IE6-8无法从HTTPS站点下载文件(IE6-8 unable to download file

2019-08-02 02:15发布

我有了返回报告文件,通常动作的MVC .NET应用程序.xslx

byte[] data = GetReport();
return File(data, 
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 
    "filename.xlsx");

这在测试和在所有浏览器的伟大工程,但是,当我们把这个失败的IE6,7和8(所有适当的浏览器仍然正常工作)这无益错误的SSL网站:

这用在传统应用(非MVC),这一行动将替换工作。

我们不能告诉我们的用户,以局部改变任何东西 - 约60%仍使用IE6!

我怎样才能解决这个使用MVC?

更新

进一步深挖发现,这是一个IE6-8根本不合格。 据埃里克·法的IE内部博客出现这种情况,因为SSL连接时,IE对待no-cache指令作为一个绝对的规则。 因此,而不是不缓存副本,它认为无缓存意味着它不应该是可能的副本,即使保存到磁盘Content-Disposition:attachment ,并与下载位置的明确提示。

显然,这是错误的,但同时它的固定在IE9我们还是坚持了所有IE6-8用户。

使用MVC的行动过滤器属性生成以下标题:

Cache-Control:no-cache, no-store, must-revalidate
Pragma:no-cache

使用招改变这些的飞行,我们可以验证需要而不是返回的标题:

Cache-Control:no-store, no-cache, must-revalidate

注意顺序Cache-Control 必须no-store no-cache ,而且Pragma指令必须完全删除。

这是一个问题 - 我们使用MVC的行动广泛属性和我真的不想从头开始重写它们。 即使我们可以,如果你尝试删除IIS抛出一个异常Pragma指令。

如何使微软的MVC和IIS返回no-cache指令,微软的IE6-8可以在HTTPS处理? 我不希望允许响应(按照本的私人缓存类似的问题 ),或者忽略内置了一个覆盖方法的MVC(按我自己的答案,这仅仅是我目前最好的破解版)。

Answer 1:

我想出了一个解决办法,但它是一个明确的黑客-这是一个新的高速缓存属性更换内置[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所需的输出。



Answer 2:

我有在类似的方法我有一个BaseController类

[OutputCache(Duration=0)]
public class BaseController : Controller
{
    //snip snip: some utility stuff and shared endpoints among all my controllers
}

这引起了IE8上述问题。 运用[IENoCacheAttribute]如上所示没有然而工作。 问题是,该指令filterContext.HttpContext.Response.ClearHeaders()删除所有我的头,包括最终Content-Disposition头等等导致文件下载到不正确的发生。

因此,我的方法是覆盖默认OutputCacheAttribute.cs以这样的方式,在IE浏览器的情况下,它不适用任何类型的缓存头,特别是有问题的no-cache的。

public class EnhancedOutputCacheAttribute : OutputCacheAttribute
{

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {

        if (!IsFileResultAndOldIE(filterContext))
            base.OnActionExecuted(filterContext);
        else
        {
            //try the best to avoid any kind of caching
            filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.Private);
            filterContext.HttpContext.Response.Cache.SetMaxAge(new TimeSpan(0));
            filterContext.HttpContext.Response.Cache.SetExpires(DateTime.Now.AddMinutes(-5D));
        }
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!IsFileResultAndOldIE(filterContext))
            base.OnActionExecuting(filterContext);
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (!IsFileResultAndOldIE(filterContext))
            base.OnResultExecuted(filterContext);
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        if (!IsFileResultAndOldIE(filterContext))
            base.OnResultExecuting(filterContext);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="filterContext"></param>
    /// <returns><c>true</c> for FileResults and if the browser is < IE9</returns>
    private bool IsFileResultAndOldIE(dynamic filterContext)
    {
        return filterContext.Result is FileResult &&
               filterContext.HttpContext.Request.IsSecureConnection &&
               string.Equals(filterContext.HttpContext.Request.Browser.Browser, "IE", StringComparison.OrdinalIgnoreCase) &&
               filterContext.HttpContext.Request.Browser.MajorVersion < 9;
    }

}

下面是相应要点: https://gist.github.com/4633225



文章来源: IE6-8 unable to download file from HTTPS site