首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Symfony Force下载响应中断文本文件

Symfony Force下载响应中断文本文件
EN

Stack Overflow用户
提问于 2014-11-10 09:22:58
回答 1查看 355关注 0票数 3

我已经根据这个答案为我的Symfony应用程序创建了一个函数:https://stackoverflow.com/a/13025363/1749653

其职能是:

代码语言:javascript
复制
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;
}

一切都很顺利..。直到有人尝试用它下载文本文件。由于某种原因,所有文本文件都以错误的文件名下载。它们都遵循这样的模式:实际_File_Name-,附件,例如: new_text.txt-,附件等等

经过一些调查,我只发现了一个不正常的文本文件作为一个整体。不知何故,响应头字段被模糊化了。其中二进制文件将输出如下所示:

代码语言:javascript
复制
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

任何文本文件都将如下所示:

代码语言:javascript
复制
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

我怀疑这种不完整的行为根植于导致内容头行为的任何原因。但我不知道这些是怎么发生的。

因此,如果有更多的人知道这些问题是如何产生的,是什么原因导致他们这样做,甚至是如何直接解决问题,那么任何帮助都将是非常感谢的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-11 09:56:17

终于弄明白了。如果某个地方有类似的问题,并发现它很有用,就把它张贴在这里:

所以。事实证明,有问题的台词是:

代码语言:javascript
复制
$response-sendHeaders()

对于二进制文件,这一行对于使其工作至关重要。但是,文本文件并不需要它,而且实际上会像上面所看到的那样中断。我还没有搞清楚它为什么会这样。但是解决方案只是简单地检查请求的文件是否是文本文件。( .html文件的构建是例外,但这更像是项目的一个可选特性/怪癖,因此可以安全地忽略它)

这就是这个函数现在看起来的样子,它的工作情况很好:

代码语言:javascript
复制
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;
}

因为我仍然不知道到底是什么导致了不同的行为,这并不像我所希望的那样安全可靠,但到目前为止,它做的还不错。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26840372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档