假设用户点击下载链接,但在弹出的“另存为”对话框中选择了取消,该如何检测这种情况?也就是说,如果用户选择了取消或者没有完整下载文件,服务器不应记录该文件已被下载。
假设用户点击下载链接,但在弹出的“另存为”对话框中选择了取消,该如何检测这种情况?也就是说,如果用户选择了取消或者没有完整下载文件,服务器不应记录该文件已被下载。
过去我已经做过这个:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
flush()
log()
exit;
日志应该在读取文件完成后运行,这意味着整个文件已经被流式传输给用户。我已经有一段时间没有做过这个了,也不知道确切的代码在哪里,所以可能不是很准确,但应该能让你开始。
编辑:我在php.net上找到了上述代码,它或多或少就是我描述的内容,这种方法应该有效。
当服务器发送文件时,它并不会立即在网络上传输,需要在客户端和服务器之间发送确认包来一次一个块地发送文件。
只需要有某种处理方式以管理方式将文件发送给用户,以便可以在文件的“最后”块刷新到用户时挂钩事件。
现在假设,用户可能永远收不到这个最后的数据块,但是如果他们请求获取最后的数据块(这就是确认包所做的),则他们或底层网络协议已接受了接收到前面所有数据块的事实,并且可以继续发送最后的数据块。
现在假设:
只需使用类似于以下的简单结构:(伪代码)。
1: Open File $foo;
2: Loop while $foo is not EOF
3: read 700kilobits from file $foo;
4: print 700kilobits of read data to web server
5: execute webserver 'flush' which blocks until flush is complete.
6: <-- Loop
7: If all chunks of 700kilobits were read before user aborted transaction
8: report file was downloaded.
编辑 Unkwntech 的回答实际上与我的回答相同。
他的回答是针对 PHP 的,而我想提供一个更通用的解决方案,主要是因为我对 PHP 开发产生了厌恶,不愿意编写代码并设置 Web 服务器来测试它是否有效,只是为了证明我从经验中知道的东西。
对于这一点我表示歉意。
你是在谈论任何文件吗?如果它是一个程序,你可以让它在安装时调用服务器吗?除此之外,我同意Jonathan的看法,我不确定你是否有权限访问那个。
дёҖз§Қж–№жі•жҳҜзј–еҶҷдёҖдәӣPHPд»Јз ҒжқҘеӨ„зҗҶдҪңдёә$_REQUESTеҸӮж•°жҸҗдҫӣзҡ„е®һйҷ…ж–Үд»¶дј йҖ’гҖӮиҜҘи„ҡжң¬е°Ҷжү§иЎҢи®°еҪ•дёӢиҪҪзҡ„е®һйҷ…е·ҘдҪңгҖӮ