IE6-8无法从HTTPS站点下载文件 [英] IE6-8 unable to download file from HTTPS site

查看:153
本文介绍了IE6-8无法从HTTPS站点下载文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MVC .Net应用程序,其中包含返回报告文件的操作,通常是 .xslx

I have an MVC .Net application that has actions that return report files, usually .xslx:

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

这在测试和所有浏览器中都很有用,但是当我们将它放在SSL站点上时它会失败对于IE6,7和8(所有正确的浏览器仍能正常工作)这个无用的错误:

This works great in testing and in all browsers, but when we put this on an SSL site it fails for IE6, 7 and 8 (all the proper browsers still work fine) with this unhelpful error:

这曾经用于此操作替换的遗留应用程序(非MVC)。

This used to work in a legacy application (non-MVC) that this action replaces.

我们无法告诉用户在本地更改任何内容 - 大约60%仍然在IE6上!

We can't tell our users to change anything locally - about 60% are still on IE6!

如何使用MVC修复此问题?

How can I fix this using MVC?

进一步挖掘表明这是IE6-8的基本失败。根据 Eric Law的IE internals blog 这是因为在SSL连接期间,IE将no-cache指令视为绝对规则。因此,它不考虑缓存副本,而是认为no-cache意味着即使
Content-Disposition:attachment 并明确提示下载位置。

Further digging reveals that this is a fundamental failure in IE6-8. According to Eric Law's IE internals blog this happens because, during an SSL connection, IE treats the no-cache directive as an absolute rule. So, rather than not cache a copy, it considers no-cache to mean that it shouldn't be possible to save a copy to disk even when Content-Disposition:attachment and with an explicit prompt for a download location.

显然这是错误的,但是当它在IE9中修复时我们仍然坚持使用所有的IE6-8用户。

Obviously this is wrong, but while it's fixed in IE9 we're still stuck with all the IE6-8 users.

使用MVC的操作过滤器属性会产生以下标题:

Using MVC's action filter attributes produces the following headers:

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

使用Fiddler动态更改这些,我们可以验证需要返回的标题:

Using Fiddler to change these on the fly we can verify the headers that need to be returned instead:

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

注意<$ c的顺序$ c> Cache-Control 必须拥有 no-store no-cache 并且 Pragma 指令必须才能删除enti依赖。

Note the order of the Cache-Control must have no-store before no-cache and that the Pragma directive must be removed entirely.

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

This is a problem - we use MVC's action attributes extensively and I really don't want to rewrite them from scratch. Even if we could IIS throws an exception if you try to remove the Pragma directive.

你如何制作微软的MVC和IIS返回Microsoft的IE6-8可以在HTTPS下处理的无缓存指令?我不想允许私人缓存响应(根据这个类似的问题)或忽略MVC内置方法的覆盖(根据我自己的答案,这只是我目前最好的黑客)。

How do you make Microsoft's MVC and IIS return the no-cache directive that Microsoft's IE6-8 can handle under HTTPS? I do not want to allow private caching of the response (as per this similar question) or ignore the MVC built in methods with an override (as per my own answer, which is just my current best hack).

推荐答案

我想出了一个解决方法,但这是一个明确的黑客 - 这是一个新的缓存属性来替换内置的 [OutputCache] one:

I've come up with a workaround, but it's a definite hack - this is a new cache attribute to replace the built-in [OutputCache] one:

[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的所需输出。

It's a workaround at best though - what I really want is to extend the existing [OutputCache] and Response.Cache structures so that they have the desired output suitable for legacy IEs.

这篇关于IE6-8无法从HTTPS站点下载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆