0

我使用X-SendFile Apache Module从服务器下载大文件。下载运行良好。但是,当下载开始时,我需要向浏览器输出一些文本,例如:“Thanks for download the file....”

我的问题是,我不能在一个脚本中同时做到这两点。我可以下载文件,然后没有文本输出到屏幕上。或者,我可以将文本输出到屏幕,但下载脚本无法启动。

请如何在一个 php 脚本中完成这两项任务 - 下载文件并将文本内容发送到浏览器/网页?问题可能源于 HTTP 输出标头,但我不知道如何解决。

这是我用来通过 X-SendFile 下载文件的示例代码(独立工作):

                header('Content-Description: File Transfer');
                header("Content-Disposition: attachment; filename=\"". basename($filePath) . "\"");
                header('Content-Transfer-Encoding: binary');
                header('Expires: 0');
                header('Cache-Control: no-store, no-cache, must-revalidate');
                header('Pragma: no-cache');
                header('Content-Length: ' . filesize($filePath));
                header("X-Sendfile: $filePath");

为了完成,这是我的测试echo""字符串。如果将它放在 X-Sendfile 代码之上,它会得到输出,但不会开始下载。如果将其放在 X-Sendfile 代码下方,则会下载文件,但不会向浏览器回显:

echo "SUCCESS!!!";
ob_flush();

约束:

我需要能够通过 URL 轻松下载文件。例如,www.mydomain.com/?fileID=asl523n53twteHLfga。换句话说,PHP 下载脚本在index.php. 当用户输入www.mydomain.com时,将显示域登录页面。但是,当附加$_GET变量被传递时,PHP 脚本会识别出来,并且应该显示Thank you for download...而不是登录页面。

欢迎提供解决方法。重要的是在保持上述约束的同时达到预期的结果。非常感谢你。

4

2 回答 2

2

有解决方法。您可以在其中创建下载文件的 iframe。有关详细信息,请参阅代码。

感谢页面:(例如 www.mydomain.com/?fileID=asl523n53twteHLfga)

<p>Thank you!</p>
<?php
$fileID = $_REQUEST['fileID'];
// csrf code individual for visitor, so visitor can's send direct link to friend
$csrf = md5(uniqid(rand(), true));
$_SESSION['csrf'] = $csrf;
// with iframe file will be downloaded 'in background'
echo '<iframe src="downloadFile.php?fileID=' . urlencode($fileID) . '&csrf=' . urlencode($csrf) . '" width="0" height="0"></iframe>';
?>

downloadFile.php(例如 www.mydomain.com/downloadFile.php?fileID=asl523n53twteHLfga)

<?php
$fileID = $_REQUEST['fileID'];
if ($_REQUEST['csrf'] == $_SESSION['csrf'])
{
    // download file
    header('Content-Description: File Transfer');
    header("Content-Disposition: attachment; filename=\"". basename($filePath) . "\"");
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: no-store, no-cache, must-revalidate');
    header('Pragma: no-cache');
    header('Content-Length: ' . filesize($filePath));
    header("X-Sendfile: $filePath");
    die();
}
else
{
    // csrf from request not equal csrf saved in session, so probably this is direct link to file received from other user
    // redirect to 'thank you' page
    header('Location: /?fileID=' . urlencode($fileID));
    die();
}
?>
于 2013-11-27T16:18:53.493 回答
2

如何添加一个单独的下载页面来下载文件(即download.php?fileID=XYZ)并让您的索引页面显示如下消息:

<?php

function homeScreen() {
  // your home content
}

function downloadFileScreen ($id) {
?>
<h2>Thank you for your download!</h2>
Your download should start automatically, if it does not, click 
<a href="download.php?fileID=<?php print $id; ?>">here</a>
<script type="text/javascript">
window.setTimeout('location.href="download.php?fileID=<?php print $id; ?>"',3000);
</script>
<?php
}

if (isset($_GET['fileID'])) {
  $id= $_GET['fileID'];
  downloadFileScreen ($id);
?>
} else {
  // no ID passed, show home screen
  homeScreen();
}
?>

我还没有听说任何浏览器支持在单个请求中混合下载和 HTTP 内容显示,但我会看看是否可以使用ob_start()and来实现ob_flush()

于 2013-11-27T16:15:08.677 回答