Php IE6中的文件下载

Php IE6中的文件下载,php,internet-explorer-6,download,Php,Internet Explorer 6,Download,我在IE6上遇到了一个相当有趣(而且令人沮丧)的问题。我们提供一些服务器生成的PDF,然后简单地在PHP中设置头文件,以强制浏览器下载该文件。除了在IE6中,一切正常,但只有在windows用户帐户设置为标准用户(即非管理员)的情况下才能工作 因为这是针对公司环境的,所以他们的所有帐户当然都是这样设置的。奇怪的是,在下载对话框中,无法识别内容类型: header( 'Pragma: public' ); header( 'Expires: 0' ); header( 'Cache-Control

我在IE6上遇到了一个相当有趣(而且令人沮丧)的问题。我们提供一些服务器生成的PDF,然后简单地在PHP中设置头文件,以强制浏览器下载该文件。除了在IE6中,一切正常,但只有在windows用户帐户设置为标准用户(即非管理员)的情况下才能工作

因为这是针对公司环境的,所以他们的所有帐户当然都是这样设置的。奇怪的是,在下载对话框中,无法识别内容类型:

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;

我还尝试先将文件内容写入一个临时文件,这样我也可以在标题中设置
内容长度
,但这没有帮助。

大约一年前,我遇到了完全相同的问题,经过大量的谷歌搜索和研究,我的标题(来自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的某些版本似乎很难做到这一点


我知道我在这里很含糊,但上面的提示是基于我使用一个web应用程序服务于包含条形码的动态构建PDF的实际经验。我不知道哪些版本会受到影响,我只知道使用上面的两个“技巧”可以消除支持呼叫:p

正如pilif已经提到的,请确保关闭服务器端gzip压缩。对我来说,这导致了PDF文件(以及其他类型的文件)的问题,也可能是因为一些不太清楚的原因,比如Internet Explorer和FireFox下的.zip文件

据我所知,zip页脚的最后一部分会被剥离(至少是被FireFox剥离),导致格式损坏

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

ini_set("zlib.output_compression",0);

下面的Java代码对我来说很有用(在Firefox2和3、IE 6和7上测试):

根本不需要其他标题。 此外,我在打开和关闭gzip压缩的情况下(使用单独的servlet过滤器进行压缩)测试了这段代码。没有任何区别(在我测试的四个浏览器中都没有任何问题)。
另外,这也适用于其他文件类型。

您可以添加一个服务器不会读取到url的附加参数,这可能也会有所帮助

我遇到过这样的情况,ie更可能读取url末尾的文件名,而不是任何标题

这些标题都是假的! 此标题是从电子邮件标题复制的。它不适用于HTTP,只是因为HTTP除了二进制之外没有任何其他传输模式。设置它与设置
X位/字节:8
一样有意义

Cache-control: pre-check=0, post-check=0
这些非标准值定义IE何时应该检查缓存内容是否仍然是新的<代码>0是默认值,因此将其设置为
0
是浪费时间。这些指令仅适用于可缓存内容,
Expires:0
必须重新验证
提示您要使其不可缓存

Content-Description: File Transfer
这是另一个电子邮件模仿者。根据设计,这个标题不会以任何方式影响下载。它只是提供信息的自由形式文本。从技术上讲,它和
X-Hi-Mom:我给你发了一个文件标题

header( 'Cache-Control: must-revalidate, pre-check=0, post-check=0' );
header( 'Cache-Control: public' );
在PHP中,第二行完全覆盖第一行。你好像在暗中捅人

什么才是真正的区别 您不必在那里插入文件名(您可以使用
mod_rewrite
index.php/fakefilename.doc
技巧–它可以更好地支持特殊字符,并在忽略可选
内容配置
标题的浏览器中工作)

在IE中,文件是否在缓存中(对于不可缓存的文件,“打开”不起作用),以及用户是否有声称支持IE检测到的文件类型的插件,这两个方面都有区别

要禁用缓存,您只需
缓存控制:无缓存
(没有20个额外的假头),并且要使文件可缓存,您无需发送任何内容

NB:PHP有一个叫做
session.cache\u limiter
的可怕的错误特性,除非将其设置为
none
,否则它会毫无希望地破坏HTTP头

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

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

如果您使用的是SSL:

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


我为此花了两天的时间,希望这条消息能帮助一些人。

只需切换到这种内容类型,它就会工作,还要确保Pragma ist设置为不等于“无缓存”的值


我很感激你们花在这篇文章上的时间。我尝试了几种组合,终于让我的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中,这对我来说都很好


希望这会对其他人有所帮助。

听起来是一个很好的借口,可以通过组策略=)在Kubuntu上部署Firefox,Apache/php5的默认设置是
session.cache\u limiter=nocache
。这是知识库文章:-标题应该设置为
header('cache-Control:private')在IE中。
Content-Disposition: attachment
ini_set('session.cache_limiter','none'); // tell PHP to stop screwing up HTTP
header( 'Content-type: application/octet-stream'); # force download, no matter what mimetype
header( 'Content-Transfer-Encoding: binary' ); # is always ok, also for plain text
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;
}