【发布时间】:2015-01-09 21:59:29
【问题描述】:
我在 NGINX 上有一个使用 PHP 服务器端语言的 Web 应用程序。通过 JS,用户可以从非常慢的数据库中下载由 PHP 动态构建的文件。因此,接收第一个字节进行打印大约需要 20 秒。然后,更多的数据在之后不断流出。
PHP:
header("Content-Disposition: attachment; filename=\"" . $filename . ".txt\"");
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Set-Cookie: fileDownload=" . $filename . "; path=/");
while (Stream::MORE_DATA == $client->receive($data)) {
print $data;
flush();
}
此下载是通过 iframe 进行的(由于其他原因,它必须保留为 iframe):
iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = downloadFileUrl;
(document.getElementsByTagName("body")[0]).appendChild(iframe);
如果用户想在新窗口中导航到另一个页面,则在下载完成之前不会加载另一个页面,因为 NGINX 一次只提供一个请求(我认为)。所以我为用户启用了一种取消下载的方法:
iframe.contentWindow.stop();
iframe.parentNode.removeChild(iframe);
如果在文件第一部分打印前的最初 20 秒内取消下载,则此操作成功。但是,如果在第一次打印后取消,即使 iframe 无效,文件仍会继续下载。
除了通过互联网浏览器的下载管理器手动取消下载之外,还有其他方法可以完全中止下载吗?
也许这可以通过 JavaScript、PHP 或 NGINX 配置更改来解决?谢谢!
【问题讨论】:
-
您是否考虑过在另一个浏览器窗口而不是 iframe 中进行下载?这样做将允许用户继续浏览/与页面交互,而不必担心停止下载。
-
感谢您的建议。我确实考虑过这样做......但是,即使请求位于单独的浏览器选项卡中,网站的其他页面也不会加载/刷新(我认为是因为 NGINX 一次只满足该 PHP 会话的一个请求) .
-
您确定这是 nginx 问题而不是 php 问题吗?在 php 中,如果您开始一个会话并且不结束它,那么在该请求结束之前,无法处理该会话的新请求。 php.net/manual/en/ref.session.php 见 session_write_close
-
我不是 php 开发人员,但是,每次使用它时,在
session_start之后不久继续使用session_write_close似乎是一个好习惯,以避免类似的并发问题。打开会话,对会话变量执行所需的操作,然后关闭它。 -
谢谢@KevinB ...这正是我正在寻找的答案。它解决了我所有的问题。
标签: javascript php iframe nginx abort