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 宇视监控服务器无法登录
  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥15 DruidDataSource一直closing
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥50 power BI 从Mysql服务器导入数据,但连接进去后显示表无数据