IE6中的文件下载

时间:2020-03-05 18:49:12  来源:igfitidea点击:

我遇到了一个与IE6相当有趣(令人沮丧)的问题。我们提供了一些服务器生成的pdf文件,然后只需在PHP中设置标头即可强制浏览器下载该文件。除了在IE6中运行外,其他所有功能都正常运行,但前提是Windows用户帐户设置为标准用户(即非管理员)。

由于这是在公司环境中使用的,因此当然可以使用这种方式来设置其所有帐户。奇怪的是,在下载对话框中,无法识别Content-Type:

header( 'Pragma: public' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate, pre-check=0, post-check=0' );
header( 'Cache-Control: public' );
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/pdf' );
header( 'Content-Disposition: attachment; filename="xxx.pdf"' );
header( 'Content-Transfer-Encoding: binary' );
echo $content;
exit;

我还尝试先将文件内容写入临时文件,这样我也可以在标头中设置" Content-Length",但这无济于事。

解决方案

回答

大约一年前,我遇到了完全相同的问题,经过大量的搜索和研究,我的标头(来自Java代码)查找IE6和PDF,如下所示:

response.setHeader("Content-Type", "application/pdf "; name=" + file.getName());
    response.setContentType("application/pdf");
    response.setHeader("Last-Modified", getHeaderDate(file.getFile());
    response.setHeader("Content-Length", file.getLength());

放下其他所有东西。

IE6,缓存,强制下载和插件显然有些不明智。我希望这对我们有用...对我来说,一个小区别是请求最初来自Flash swf文件。但这无关紧要。

回答

某些版本的IE似乎需要

header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate, pre-check=0, post-check=0' );

过于认真,请先删除下载的内容,然后再将其传递给插件以显示它。

删除这两个,就可以了。

并确保在使用PDF时不使用任何服务器端GZIP压缩,因为某些版本的Acrobat似乎为此感到困扰。

我知道我在这里含糊不清,但以上技巧是基于我使用网络应用程序提供的动态经验而得出的,该应用程序可动态构建包含条形码的PDF。我不知道受影响的版本,我只知道使用上面的两个"技巧"使支持电话消失了:p

回答

正如pilif已经提到的,请确保关闭服务器端gzip压缩。对我来说,这引起了PDF文件(以及其他类型)的问题,并且由于可能(不是很晦涩的原因)也导致了Internet Explorer和FireFox下的.zip文件出现问题。

据我所知,zip页脚的最后一位将被剥离(至少被FireFox剥离),从而导致格式损坏。

在PHP中,我们可以使用以下代码:

ini_set("zlib.output_compression",0);

回答

以下Java代码对我有用(在Firefox 2和3,IE 6和7上测试):

response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
response.setContentType(getServletContext().getMimeType(file.getName()));
response.setContentLength(file.length());

根本不需要其他头。
另外,我在打开和关闭gzip压缩的情况下都测试了此代码(使用单独的servlet过滤器进行压缩)。没什么区别(在我测试过的四种浏览器中都可以正常工作)。
另外,这也适用于其他文件类型。

回答

我们可以添加一个服务器将不会读取的添加参数,这可能也有帮助。

http://www.mycom.com/services/pdf?action=blahblah&filename=pdf0001.pdf

我遇到过这样的情况,即,与任何标题相比,ie更有可能读取url末尾的文件名

回答

这些标题是伪造的!

Content-Transfer-Encoding: binary

此标题是从电子邮件标题复制的。它不仅仅适用于HTTP,因为HTTP除了二进制以外没有其他传输方式。设置它与设置" X-Bits-Per-Byte:8"一样有意义。

Cache-control: pre-check=0, post-check=0

这些非标准值定义IE应该何时检查缓存的内容是否仍然新鲜。默认值为0,因此将其设置为0是浪费时间。这些指令仅适用于可缓存的内容,而Expires:0must-revalidate暗示我们要使其成为不可缓存的内容。

Content-Description: File Transfer

这是另一个电子邮件模仿者。按照设计,此标头不会以任何方式影响下载。这只是内容丰富的自由格式文本。从技术上讲,它与" X-Hi-Mom:我要向我们发送文件!"标头一样有用。

header( 'Cache-Control: must-revalidate, pre-check=0, post-check=0' );
header( 'Cache-Control: public' );

在PHP中,第二行完全覆盖第一行。你似乎在黑暗中刺伤。

真正有什么不同

Content-Disposition: attachment

我们不必在其中插入文件名(可以使用mod_rewrite或者index.php / fakefilename.doc技巧,它为特殊字符提供了更好的支持,并且可以在忽略可选的Content-Disposition标头的浏览器中使用) 。

在IE中,文件是否在缓存中("不可打开"不适用于不可缓存的文件)以及用户是否具有声称支持IE检测到的文件类型的插件都将有所不同。

要禁用缓存,我们只需要Cache-control:no-cache(没有20个额外的假头),并且使文件可缓存,我们无需发送任何内容。

注意:PHP具有可怕的功能错误,称为" session.cache_limiter",除非将其设置为" none",否则它毫无希望地破坏了HTTP标头。

ini_set('session.cache_limiter','none'); // tell PHP to stop screwing up HTTP

回答

我有一个类似的问题,但可能不完全相关。我的问题是IE6似乎在文件名中存在特殊字符(特别是斜杠)的问题。删除这些可解决问题。

回答

如果我们使用的是SSL:

确保我们不包括任何缓存控件(或者Pragma)标头。 IE6中存在一个错误,如果使用了缓存控制标头,它将阻止用户下载文件。他们将收到错误消息。

我将头发拉了两天,因此希望此消息对某人有所帮助。

回答

只需切换到该内容类型即可使用,并且还要确保将Pragma ist设置为不等于" no-cache"的值

header( 'Content-type: application/octet-stream'); # force download, no matter what mimetype
header( 'Content-Transfer-Encoding: binary' ); # is always ok, also for plain text