【问题标题】:php script to download files from a remote URL to the user's computer directly [closed]php脚本从远程URL直接下载文件到用户的计算机[关闭]
【发布时间】:2016-04-06 21:48:36
【问题描述】:

我希望网站用户能够轻松下载我们在远程托管服务上拥有的文件(音频)。

我们有指向这些文件的 URL。这些文件与主站点不在同一站点或服务器上。

目前我们有指向这些文件的链接,以及一些指示站点用户必须右键单击并选择“文件另存为”才能将这些文件下载到本地计算机的文本。

为了使这更加用户友好,如果站点用户只需单击一个链接并拥有一个可以下载文件的脚本,那就更好了。

这可能吗?

对此进行研究后,有许多在线示例和关于在同一服务器上下载文件或将 URL 下载到您的服务器的 SO 问题。

这不是我们想要在这里做的。我们不想将这些文件中的任何一个从远程托管服务复制到主 Web 服务器。

这是让站点用户单击链接并让远程 URL 将文件直接下载到用户的本地计算机,而不是服务器。

【问题讨论】:

  • 如果您只左键单击现有链接会发生什么?
  • 用户点击远程 url 上的链接有什么问题,而托管服务只需发送正确的标头即可开始下载?
  • 我们无法控制远程托管服务器,只能控制主网站。如果您左键单击该文件,它将尝试在用户的浏览器中播放。这不是我们需要发生的事情。这些链接必须是“下载”链接,用户才能将文件下载到他们的机器上,而不是播放文件。
  • 如果您无法控制服务器,那么您无能为力。在不将文件复制到您自己的服务器的情况下,唯一的解决方案是将您的服务器用作一种代理,以便您可以设置适当的标头。麻烦的是,PHP 每次都必须检索远程文件。这会节省您的存储空间,但显然不会节省带宽。您的用户还必须等待您的服务器下载文件。不理想。

标签: php html


【解决方案1】:

您可以使用以下 PHP 实现此目的:

$file_name = $_GET['filename'];
$file_url = 'http://path_to_audio_folder.com/' . $file_name;
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary"); 
header("Content-disposition: attachment; filename=\"".$file_name."\""); 
readfile($file_url);
exit;

然后您可以从您的脚本中调用它,例如:download.php?filename=my_song.mp3,它会被强制下载给您的访问者点击它。

【讨论】:

  • 这是一个不错的简单解决方案,而且效果很好。谢谢!
  • 我们可以更改文件名吗?
  • @VermaJr。你能澄清一下吗?如果您的意思是filename=my_song.mp3 - 只要它存在于您的目录中并且是公开的,它将采用任何 MP3 文件名。
  • @RyanA 我得到了答案。
【解决方案2】:

您可能想要构建一个“代理页面”。您的服务器下载文件,同时将数据发送给您的最终用户。最简单的方法是在 chunks 中输出文件:

$url = 'http://.....mp3';

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($url));
header('Content-Transfer-Encoding: chunked'); 
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');

$stream = fopen('php://output', 'w');

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_READFUNCTION, function($ch, $fd, $length) use ($stream) {
    return fwrite($stream, fread($fd, $length));
});

curl_exec($ch);
curl_close($ch);

分块Content-Transfer-Encoding 允许客户端在知道Content-Length 字段之前开始传输文件。有了这个,用户在开始下载之前不需要等待服务器完全下载文件。

【讨论】:

  • 对不起,你能帮帮我吗:我需要一些东西来下载文件并将其发送给用户并从服务器中删除下载的流。因为我的服务器目录中的文件空间有限
猜你喜欢
  • 2013-03-24
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
  • 2016-03-26
  • 1970-01-01
  • 2013-09-25
  • 2010-11-26
  • 2012-07-09
相关资源
最近更新 更多