我已根据以下答案为我的Symfony应用程序创建了一个函数:https://stackoverflow.com/a/13025363/1749653
功能如下:
public function getForceDownloadResponse($file_path, $file_name){
$file_info = finfo_open(FILEINFO_MIME_TYPE);
$mine_type = finfo_file($file_info, $file_path.$file_name);
finfo_close($file_info);
$response = new Response();
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', $mine_type);
$response->headers->set('Content-Disposition', 'attachment; filename="' . $file_name . '"');
$response->headers->set('Content-length', filesize($file_path.$file_name));
$response->sendHeaders();
$response->setContent(readfile($file_path.$file_name));
return $response;
}
这一切都很顺利......直到有人试图用它下载文本文件。 出于某种原因,所有文本文件都以错误的文件名下载。他们都遵循这种模式: Actual_File_Name-,附件 所以,例如:new_text.txt-,附件 等
经过一番调查后,我发现只有一个不整齐的文本文件。不知何故,响应头字段被公开。 二进制文件将输出如下内容:
Cache-Control:private
Connection:close
Content-Disposition:attachment; filename="Jellyfish.jpg"
Content-Length:775702
Content-Type:image/jpeg
Date:Mon, 10 Nov 2014 09:14:41 GMT
Server:Apache/2.4.7 (Win32) OpenSSL/1.0.1e PHP/5.5.6
任何文本文件都如下所示:
Cache-Control:private
Cache-Control:private
Connection:Keep-Alive
Content-Disposition:attachment; filename="full.txt"
Content-Disposition:attachment; filename="full.txt"
Content-Length:15
Content-Type:text/plain; charset=UTF-8
Date:Mon, 10 Nov 2014 09:06:00 GMT
Keep-Alive:timeout=5, max=97
Server:Apache/2.4.7 (Win32) OpenSSL/1.0.1e PHP/5.5.6
我怀疑无内容行为根据内容标题行为的原因而存在。但我不能为我的生活弄清楚这些是怎么发生的。
所以,如果有人知道更多关于这些是如何创建的,可能会导致他们表现得如此,或者甚至如何彻底解决问题,那么任何帮助都会非常感激。
答案 0 :(得分:0)
终于明白了。在这里发布以防某人,某处有类似问题并发现它有用:
因此。事实证明,问题在于:
$response-sendHeaders()
对于二进制文件,此行对于使其工作至关重要。文本文件不需要它,实际上会像上面看到的那样破坏。我还没有找到'为什么'它的行为。但解决方案是简单地检查所请求的文件是否是文本文件。 (对.html文件构建异常,但这更多是项目的可选功能/怪癖,因此可以安全地忽略)
这就是现在的功能,它的工作正常:
public function getForceDownloadResponse($file_path, $file_name){
$file_info = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($file_info, $file_path.$file_name);
$text = (substr(finfo_file($file_info, $file_path.$file_name), 0, 4) == 'text') ? 1 : 0;
finfo_close($file_info);
$response = new Response();
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', $mime_type);
$response->headers->set('Content-Disposition', 'attachment; filename="' . $file_name . '"');
$response->headers->set('Content-length', filesize($file_path.$file_name));
if(!$text || $mime_type == 'text/html'){
$response->sendHeaders();
}
$response->setContent(readfile($file_path.$file_name));
return $response;
}
因为我仍然不知道究竟是什么导致了不同的行为,所以它不像我希望的那样安全和可靠,但到目前为止,它的工作做得很好。