例如,我使用此表单提交下载文件。
if(!isset($hasError) {
//some code here.
$file_url = "http://example.com/files/download/file.pdf";
header("Expires: 0");
header("Cache-Control: no-cache, no-store, must-revalidate");
header('Cache-Control: pre-check=0, post-check=0, max-age=0', false);
header("Pragma: no-cache");
header("Content-type: {$content_type}");
header("Content-Disposition:attachment; filename={$file_new_name}");
header("Content-Type: application/force-download");
flush();
readfile("{$file_url}");
exit();
}
使用上面的提交表单,它将返回可下载的文件进行保存。 正如我在Chrome上看到的那样(Ctrl + J),不会显示下载链接。它仅显示带有操作的表单链接。 但是访问者可以知道这样的实际链接:“http://example.com/files/download/file.pdf”。
如果他们能找到该链接,任何解决方案都可以防止这种情况发生?
非常感谢你。
答案 0 :(得分:1)
不,从浏览器中找不到源链接,PHP脚本在输出中传递远程文件内容,这正是readfile
函数的作用,它读取内容的缓冲区并将其回显给浏览器没有泄露任何信息。
浏览器没有办法知道任何事情,用户只能对响应速度进行一些时序分析,以了解文件是服务器本地还是远程文件,但不超过(仍然不知道)在哪里"远程"是。
答案 1 :(得分:1)
您可以在Incorrect datetime value: '2018040305000'
中添加.htaccess
Deny from all
以禁止直接访问(= HTTP请求),但使用readfile可以读取该文件。
注意:您需要使用readfile函数并流式传输您的请求(对于大文件):https://www.media-division.com/the-right-way-to-handle-file-downloads-in-php/& https://www.media-division.com/php-download-script-with-resume-option/
答案 2 :(得分:1)
manual page for readfile()说(强调我的):
返回值
返回从文件中读取的字节数。如果发生错误, 返回FALSE,除非函数被调用为@readfile(), 打印出错误消息。
对@
的引用甚至不是特别正确,因为您可以使用忽略它的自定义错误处理程序。这意味着,根据您的服务器配置,您可以将URL打印为输出的一部分。例如,按原样运行代码将在我的计算机中打印出来:
Warning: readfile(http://example.com/files/download/file.pdf): failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found in Standard input code on line 13
通过确保永远不会向用户显示错误消息,可以避免此(以及类似问题)。这通常涉及在生产环境中将display_errors
设置为false
,并且在这种情况下,确保正确处理警告(使用@
或使用custom error handler)。
在任何情况下,受保护的下载通常都使用受密码保护的位置和/或临时链接进行处理。代理服务器并不隐藏这样一个事实,即可以自由下载该文件的开放式互联网服务器。
注意:这个答案是在假设网络下载正在使用的情况下编写的,因为它是一个远程资源。使用HTTP获取本地文件相当于在互联网上共享桌面以使用Google Chrome打开文件,而不是双击文件管理器。构建受保护下载系统的正确方法是将文件移动到公共Web服务器根目录之外,并使用本地文件系统路径提供readfile()
,例如:
readfile('/home/foo/private/file.pdf');
这样,意外泄露本地路径不是安全问题。但是,如上所述,这是一个不同的问题。