我的客户端有一个下载按钮。 单击按钮后,使用PHP在服务器上设置一些标题以启动下载。
//code snippet:
$filename = basename($datei);
$size = filesize($datei);
$this->response->setHeader('Content-Type', "application/force-download", TRUE);
$this->response->setHeader('Content-Disposition', 'attachment; filename='.$filename , TRUE);
$this->response->setHeader('Content-Length', $size, TRUE);
return "TEST"; //<--code will never go this far, it is ignored
下载有效。但我从来没有得到一些回复作为回应但头部。 我该怎么回事下载开始后的字符串?
设置标题后似乎无法向客户端返回内容。
背景
基本上我的目标是显示和隐藏微调器图标,例如在文件仍在下载时在下载按钮内显示微调器图标,并在下载完成后再次隐藏它。 因此,为了知道下载是否已经完成,我想我可以从服务器向客户端返回一些东西,让客户知道它,例如&#34;下载成功&#34;。
但我不确定这是否会起作用,也许响应会在下载完成之前到达。
答案 0 :(得分:2)
你不能。不要浪费你的时间来寻找黑客,而是相应地设计你的下载页面。
当你告诉浏览器(使用标题)你将提供一个像这里一样下载的文件时
$this->response->setHeader('Content-Type', "application/force-download", TRUE);
然后所有相当新的浏览器都会遵循该建议并下载文件,之后他们不关心PHP是否设法在最后回应某些内容,他们不需要它。
您的PHP代码不被忽略,处理得很好。在为浏览器提供一些标题后,PHP不会阻止您使用任何代码。只是一旦你告诉客户你要返回一个文件下载它就不会打扰你想要输出的其他文本。实际上,这将被视为下载文件的一部分。您没有在自己的文件中看到它,因为它的return
在此内容中无用,请尝试使用echo
。
当您提供内容类型标题时,如果您希望浏览器成功了解服务器的响应,则需要发送完全相同类型的内容。
查看所有主要下载站点,几乎所有主要下载站点都设置了下载链接,这样当您单击下载链接时,您将被重定向到另一个页面,其中显示“您的下载将很快开始......”同时他们向他们的下载页面发起另一个请求就是这样做的;提供要下载的文件。
因此,在一个请求中,您无法将两者完美地混合在一起,并具有相当多的浏览器兼容性。
答案 1 :(得分:0)
要结束当前脚本,您可以使用return
,但是当在顶级脚本中使用时(如您所见),它将结束执行但不会传回任何返回值或输出任何内容作为部分HTTP响应。您需要exit
(请参阅后面的内容)。
return
只能将值传回调用脚本:
要结束当前脚本并输出值作为HTTP响应的一部分,您可以使用 exit
(http://php.net/manual/en/function.exit.php)或die
(与出口)。但是exit
可以在传递参数时更改其行为:
输出任何东西以获得&#34;返回&#34;作为HTTP响应的一部分,请使用echo
。 (http://php.net/manual/en/function.echo.php)。这将输出任何可以转换为字符串的内容(即输出整数或字符串),如果整数或字符串为exit
,则不会更改行为。
因此,最安全的选择是:
echo
作为HTTP响应的一部分发送回来exit
来结束执行; 理想情况下(为避免代码中存在潜在的歧义)HTTP响应,除非您为命令行界面进行编程,否则不要将返回值添加到exit。即对于HTTP,请使用
// Outputs something and exists
echo 'TEST';
exit;
或
// Outputs something and exists
echo 1;
exit;
如果您要输出文件(而不是内存中的变量),请查看readfile()
(http://php.net/manual/en/function.readfile.php),它会将文件流输出到HTTP响应。 (后跟exit;
)
// Outputs a file to HTTP response
readfile('/path/To/My/File/MyFile.txt');
exit;
*加分说明:exit
,echo
和return
本身不是函数,而是语言结构。不应在括号中指定exit
和return
的返回值。它可以工作,但PHP手册建议不要使用它。 echo
可以使用参数,如果您要传递多个值,则必须使用参数。
错:
正确:
答案 2 :(得分:-1)
我正在使用MVC框架,在我的控制器中我有一个方法可以执行此操作,并且无需重新加载启动下载的父页面:
// Define headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file_name");
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
// Read the file
readfile($filePath);
exit;