我有
<a>
并且在其 href
属性内,我从第 3 方 api 获得了视频 URL,当单击该 <a>
时,浏览器会打开一个新选项卡并 播放视频而不是下载视频!
问题:我需要实现的是点击
<a>
后直接下载视频,而不是在新选项卡中播放视频并强制用户Right Click
然后选择Save Video As
选项手动下载。 .. 只需点击 Download
,浏览器就会开始下载该视频!
注意:我正在构建一个JavaScript应用程序,所以我需要一个JavaScript而不是PHP的解决方案,它也必须适用于所有浏览器......
由于端点支持 CORS,因此您可以使用 我的文件下载库 来保存内容而不是显示内容。
download("http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4");
您需要从服务器设置标头,例如Content-Disposition,如下所示
Content-Description: File Transfer
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="filename.jpg"
为了允许预览和下载,您可以根据查询参数附加这些标头,例如,如果网址有
?download
,则附加这些标头以告诉浏览器下载文件而不是查看文件。
您无法更改第 3 方服务器的标头。
您不想实现可以代理请求并更新标头的服务器。
我能看到的唯一解决方案是使用
request
或 axios
下载并处理浏览器 js 中的内容,然后向用户建议(但你必须将其保留在内存中,这可能不适合大视频)
由于它是来自第 3 方 api 的视频 URL,因此您可以通过两种方式解决该问题:
是的,关键是在http响应中设置content-type header。
我可以理解,OP 特别需要针对 CORS 问题的情况(即视频 URL 和 JS url 来源不同)的情况提供解决方案。
但是我将这个答案发布给任何想要实现类似目标并且没有 CORS 问题的人。
本质上,您可以使用 fetch API 下载文件,将其保存为 Blob,并将其挂钩到动态创建的锚标记,如下面的代码片段所示。 只需在单击“下载”按钮时触发以下功能并传递视频网址以及您想要将其另存为的文件名即可。
const downloadMedia = async (videoUrl, fileName) => {
const blob = await fetch(url).then((res) => res.blob())
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onloadend = function() {
const elem = document.createElement('a')
elem.download = fileName
if (typeof reader.result === 'string') {
elem.href = reader.result
}
elem.click()
}
}
我最好的猜测是将用户重定向到单独的页面,以强制浏览器下载文件而不是查看它(图像、视频、pdf)
使用 readfile 函数创建 download.php 文件的 PHP 示例
<?php
$file = 'monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
希望有帮助。