dqrfdl5708 2019-01-31 12:01
浏览 71
已采纳

使用PHP下载readfile()适用于Firefox,但不适用于Chrome

I am having a problem with my webpage. I am building a report tool for downloading data as .csv - I have a php skript which aggregates the data and builds a csv from it. The skript is invoked with the exec() command, detailed code is below. The skript itself uses file_put_contents() to generate the file, which is then stored in my /tmp/ folder until its downloaded (I am working in a dockerized environment and our filter rules delete the file at the next request, but I could store the file permanently somewhere else if that would be neccessary). I am then checking if the file is present with file_exists() and proceed to invoke my download function. In Firefox I get the desired result, a file with the correct content of only the csv data.

My main Problem is: When I download the csv in Chrome I get the csv data followed by the html source of my page - so starting with <!doctype html> in the first line after the csv data, then <html lang="de">in the next line of te csv and so on..

Let me show you some code:

In my skript:

private function writeToFile($csv)
{
    $fileName = '/path/to/file' '.csv';
    echo "
" . 'Write file to ' . $fileName . "
";
    file_put_contents($fileName, $csv);
}

In my page class:

    $filePath = '/path/to/finished/csv/'
    exec('php ' . $skriptPath . $skriptParams);
    if (file_exists($filePath)) {
        $this->downloadCsv($filePath);
    } else {
        $pageModel->addMessage(
            new ErrorMessage('Error Text')
        );
    }

My download function in the same class:

private function downloadCsv($filePath)
{
    header('Content-Description: File Transfer');
    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
    header('Content-Length: ' . filesize($filePath));
    readfile($filePath);
}

The shown above is working in Firefox, but not in Chrome. I already tried to clear the output buffer with ob_clean() or send and disable it with ob_end_flush() but nothing worked for Chrome.

I also tried something like this in my download function:

    header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');

    $fp =fopen($filePath, 'rw');
    fpassthru($fp);
    fclose($fp);

This produces the same results in Firefox and Chrome - I get the csv data followed by the html sourcecode mixed into the same file.

I am working within a Symfony framework if that could be from help, I saw there are some helper functions for file downloads but I so far I could not use them with success..

Until now my target is only to get the download working in Chrome to have a working mvp which can go into production - it is supposed to be for internal use only, so I don't have to care about IE or some other abominations because our staff is told to use a normal browser... But when someone sees flaws in the general concept feel free to tell me!

Thanks in advance :)

  • 写回答

1条回答 默认 最新

  • doufu7464 2019-02-09 00:24
    关注

    So I managed to get it working, I was on the wrong track with the output buffer, but a simple exit()after my readfile()was enough to stop parts of the html ending up in the csv file.

    Code:

    private function downloadCsv($filePath)
    {
        header('Content-Description: File Transfer');
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
        header('Content-Length: ' . filesize($filePath));
        readfile($filePath);
        exit;
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 请提供一个符合要求的网页链接。
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码