Reputation: 981
I have <a>
and inside its href
attribute, I've got a Video URL from a 3rd-party api, when clicking on that <a>
the browser opens a New Tab and Play the video instead of Downloading it!
PROBLEM: What I need to achieve is to download the video directly after clicking on that <a>
instead of playing it in a New Tab and force the user to Right Click
then choose Save Video As
option to download it manually... Just click on Download
and the browser starts to download that video!
NOTE: I am building a JavaScript App, so I need a solution in JavaScript not PHP, it has to be working on all browsers as well...
EDIT: I tried the download
attribute and it doesn't work, because it's Same-Origin Only!
UPDATE: The only solution I found was a +7 years old, it manipulates with the .htaccess
file, you can check it at this CSS Tricks Article, it has a common issue, I can't have 2 links: Watch Video
and Download Video
using this solution... Many developers mentioned this bug there, but no one fixed it yet!
Upvotes: 6
Views: 11176
Reputation: 3441
I can understand that the OP specifically needs a solution for the case where CORS is an issue (i.e video URL and JS url are of different origins).
But I am posting this answer for anyone who wants to achieve something similar, and doesn't have the CORS issue.
Essentially, you can download the file using the fetch API, save it as a Blob, and hook it to a dynamically created anchor tag as in the snippet below. Just trigger the below function when your "download" button is clicked and pass the video url, and the file name you'd like to save it as.
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()
}
}
Upvotes: 0
Reputation: 16726
Since the endpoint supports CORS, you can use my file download lib to save the content instead of showing it.
download("http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4");
Online Demo: http://pagedemos.com/v84rawmzntzt/output/
Upvotes: 4
Reputation: 645
As it is a Video URL from a 3rd-party api, you can resolve the problem in two ways:
Yes, the key is to set content-type header in http response.
Upvotes: 0
Reputation: 177
My best guess would be redirecting user to a separate page to force browser download the file instead of viewing it (image, video, pdf)
PHP Example using readfile function create a download.php file
<?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;
}
?>
Hope that helps.
Upvotes: -1
Reputation: 670
You can't change the header of the 3rd party server.
You don't want to implement a server that could proxying the request and update the header.
The only solution I can see is download and handling the content in browser js with request
or axios
then propose it to user (but you have to keep it in memory which might not fit for large video)
Upvotes: 1
Reputation: 2166
you need to set headers such as Content-Disposition from the server as follows
Content-Description: File Transfer
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="filename.jpg"
to allow previewing and download you might append these headers depending on query parameter for example if the url has ?download
, append these headers to tell the browser to download the file instead of viewing it.
Upvotes: 0