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