使用 PHP readfile() 下载在 Firefox 中有效,但在 Chrome 中无效
Download with PHP readfile() works in Firefox, but not in Chrome
我的网页有问题。我正在构建一个报告工具,用于将数据下载为 .csv - 我有一个 php skript,它聚合数据并从中构建一个 csv。使用exec()
命令调用skript,详细代码如下。 skript 本身使用 file_put_contents()
生成文件,然后存储在我的 /tmp/ 文件夹中直到下载(我在 dockerized 环境中工作,我们的过滤规则在下一个请求时删除文件,但我可以如果有必要,将文件永久存储在其他地方)。然后我检查文件是否存在 file_exists()
并继续调用我的下载功能。在 Firefox 中我得到了想要的结果,一个只有 csv 数据的正确内容的文件。
我的主要问题是: 当我在 Chrome 下载 csv 时,我得到了 csv 数据,然后是我页面的 html 源 - 所以在 csv 数据之后的第一行中以 <!doctype html>
开始,然后在 te csv 的下一行中以 <html lang="de">
等等..
让我给你看一些代码:
在我的脚本中:
private function writeToFile($csv)
{
$fileName = '/path/to/file' '.csv';
echo "\n" . 'Write file to ' . $fileName . "\n";
file_put_contents($fileName, $csv);
}
在我的页面中 class:
$filePath = '/path/to/finished/csv/'
exec('php ' . $skriptPath . $skriptParams);
if (file_exists($filePath)) {
$this->downloadCsv($filePath);
} else {
$pageModel->addMessage(
new ErrorMessage('Error Text')
);
}
我的下载功能也一样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);
}
上面显示的在 Firefox 中有效,但在 Chrome 中无效。 我已经尝试清除输出缓冲区使用 ob_clean()
或使用 ob_end_flush()
发送和禁用它,但对 Chrome 没有任何效果。
我也在我的下载功能中尝试过类似的东西:
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
$fp =fopen($filePath, 'rw');
fpassthru($fp);
fclose($fp);
这在 Firefox 和 Chrome 中产生相同的结果 - 我将 csv 数据后跟 html 源代码混合到同一个文件中。
我正在 Symfony 框架内工作,如果可以的话,我看到有一些用于文件下载的辅助函数,但到目前为止我无法成功使用它们..
到现在为止,我的目标只是让下载在 Chrome 中正常运行,以获得可以投入生产的有效 mvp - 它应该仅供内部使用,所以我不必关心 IE 或其他一些令人厌恶的东西,因为我们的员工被告知要使用普通浏览器...但是当有人发现一般概念中的缺陷时,请随时告诉我!
提前致谢:)
所以我设法让它工作,我在输出缓冲区的错误轨道上,但是在我的 readfile()
之后一个简单的 exit()
就足以停止部分 html 以 csv 文件结尾。
代码:
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;
}
我的网页有问题。我正在构建一个报告工具,用于将数据下载为 .csv - 我有一个 php skript,它聚合数据并从中构建一个 csv。使用exec()
命令调用skript,详细代码如下。 skript 本身使用 file_put_contents()
生成文件,然后存储在我的 /tmp/ 文件夹中直到下载(我在 dockerized 环境中工作,我们的过滤规则在下一个请求时删除文件,但我可以如果有必要,将文件永久存储在其他地方)。然后我检查文件是否存在 file_exists()
并继续调用我的下载功能。在 Firefox 中我得到了想要的结果,一个只有 csv 数据的正确内容的文件。
我的主要问题是: 当我在 Chrome 下载 csv 时,我得到了 csv 数据,然后是我页面的 html 源 - 所以在 csv 数据之后的第一行中以 <!doctype html>
开始,然后在 te csv 的下一行中以 <html lang="de">
等等..
让我给你看一些代码:
在我的脚本中:
private function writeToFile($csv)
{
$fileName = '/path/to/file' '.csv';
echo "\n" . 'Write file to ' . $fileName . "\n";
file_put_contents($fileName, $csv);
}
在我的页面中 class:
$filePath = '/path/to/finished/csv/'
exec('php ' . $skriptPath . $skriptParams);
if (file_exists($filePath)) {
$this->downloadCsv($filePath);
} else {
$pageModel->addMessage(
new ErrorMessage('Error Text')
);
}
我的下载功能也一样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);
}
上面显示的在 Firefox 中有效,但在 Chrome 中无效。 我已经尝试清除输出缓冲区使用 ob_clean()
或使用 ob_end_flush()
发送和禁用它,但对 Chrome 没有任何效果。
我也在我的下载功能中尝试过类似的东西:
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
$fp =fopen($filePath, 'rw');
fpassthru($fp);
fclose($fp);
这在 Firefox 和 Chrome 中产生相同的结果 - 我将 csv 数据后跟 html 源代码混合到同一个文件中。
我正在 Symfony 框架内工作,如果可以的话,我看到有一些用于文件下载的辅助函数,但到目前为止我无法成功使用它们..
到现在为止,我的目标只是让下载在 Chrome 中正常运行,以获得可以投入生产的有效 mvp - 它应该仅供内部使用,所以我不必关心 IE 或其他一些令人厌恶的东西,因为我们的员工被告知要使用普通浏览器...但是当有人发现一般概念中的缺陷时,请随时告诉我!
提前致谢:)
所以我设法让它工作,我在输出缓冲区的错误轨道上,但是在我的 readfile()
之后一个简单的 exit()
就足以停止部分 html 以 csv 文件结尾。
代码:
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;
}