在IE6中下载文件

时间:2008-09-08 07:49:37

标签: php internet-explorer-6 download

我遇到了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,但这没有帮助。

10 个答案:

答案 0 :(得分:4)

这些标题是假的!

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: I'm sending you a file!标题一样有用。

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

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

真正有所作为

Content-Disposition: attachment

您不必在那里插入文件名(您可以使用mod_rewriteindex.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

答案 1 :(得分:3)

某些版本的IE似乎需要

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

太认真了,并且在将下载的内容传递给插件之前将其删除以显示它。

删除这两个,你应该没事。

在使用PDF时,请确保您没有使用任何服务器端GZIP压缩,因为某些版本的Acrobat似乎很难解决这个问题。

我知道我在这里很模糊,但上面的提示基于我使用Web应用程序提供的实际经验,该应用程序提供包含条形码的动态构建的PDF。我不知道哪些版本受到影响,我只知道使用上面的两个“技巧”使得支持电话消失了:p

答案 2 :(得分:1)

一年前我遇到了完全相同的问题,经过大量的谷歌搜索和研究,我的标题(来自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文件。但那应该不重要。

答案 3 :(得分:1)

我感谢你们在这篇文章上花的时间。我尝试了几种组合,最后得到了我的symfony项目。在这里,我发布解决方案,以防任何人遇到同样的问题:

public function download(sfResponse $response) {

        $response->clearHttpHeaders();
        $response->setHttpHeader('Pragma: public', true);
        $response->addCacheControlHttpHeader("Cache-control","private");        
        $response->setContentType('application/octet-stream', true);
        $response->setHttpHeader('Content-Length', filesize(sfConfig::get('sf_web_dir') .       sfConfig::get('app_paths_docPdf') . $this->getFilename()), true);
        $response->setHttpHeader("Content-Disposition", "attachment; filename=\"". $this->getFilename() ."\"");
        $response->setHttpHeader('Content-Transfer-Encoding', 'binary', true);
        $response->setHttpHeader("Content-Description","File Transfer");
        $response->sendHttpHeaders();
        $response->setContent(readfile(sfConfig::get('sf_web_dir') . sfConfig::get('app_paths_docPdf') . $this->getFilename()));

        return sfView::NONE;
}

在IE6,IE7,Chrome,Firefox中,这对我来说很合适。

希望这会对某人有所帮助。

答案 4 :(得分:0)

正如pilif已经提到过的,请务必关闭服务器端的gzip压缩。对我来说,这会导致PDF文件(以及其他类型)出现问题,并且因为Internet Explorer和FireFox下的.zip文件也可能不那么模糊。

据我所知,压缩页脚的最后一位会被剥离(至少是FireFox)导致格式损坏。

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

ini_set("zlib.output_compression",0);

答案 5 :(得分: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过滤器)。没有任何区别(在我测试过的四个浏览器中没有任何问题)。 另外,这也适用于其他文件类型。

答案 6 :(得分:0)

您可以将服务器无法读取的其他参数添加到它可能有用的网址中。

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

我遇到过哪种情况,即更有可能读取网址末尾的文件名而不是任何标题

答案 7 :(得分:0)

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

答案 8 :(得分:0)

如果您使用的是SSL:

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

我把头发拉了两天,所以希望这个消息有助于某人。

答案 9 :(得分:0)

只需切换到此内容类型即可使用,同时确保Pragma设置为不等于“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