PHP,X-发送文件:发送文件并输出文本到浏览器(通过回显)

aydmsdu9  于 2023-01-24  发布在  PHP
关注(0)|答案(2)|浏览(173)

我使用X-SendFile Apache Module从服务器下载大文件,下载运行良好,但是当下载开始时,我需要向浏览器输出一些文本,例如:“感谢您下载文件....”
我的问题是,我不能在一个脚本中同时完成这两个任务。我可以下载文件,但没有文本输出到屏幕上;或者,我可以将文本输出到屏幕上,但下载脚本不会启动。

**如何在一个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脚本识别出这一点,并应显示 * 谢谢您下载... * 而不是登录页。
变通方案是受欢迎的。重要的是在保持上述约束的同时达到预期的结果。非常感谢。

fwzugrvs

fwzugrvs1#

添加一个单独的下载页面来下载文件(例如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()ob_flush()实现这一点。

owfi6suc

owfi6suc2#

有一个变通方案。你可以创建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>';
?>

下载文件(例如: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();
}
?>

相关问题