0

I want to download certain videos with a click. For that, I created a Button and attached a Function that should trigger the associated video download. But I am only able to download the link of the video, not the video. I am able to download videos with an external downloader or simply drag the URL to the download section of the browser. But unable to trigger that activity via JavaScript. Please help Me.

I tried multiple ways to tackle this problem:

  1. Using a Simple Blob Technique without Axios:
const blob = new Blob([this.src_url], { type: 'video/mp4' })
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = this.src_url.replace(
>!     //   'https://redis-test.com/videos/',


link.click()
URL.revokeObjectURL(link.href)

endpoint: video URL get downloaded as a file of 122 bytes

  1. Then using File Saver Package:
    var FileSaver = require('file-saver')
    console.log(this.src_url)  
    var blob = new Blob([this.src_url], { type: 'video/mp4' })
    FileSaver.saveAs(blob, 'hello world.mp4')
  1. Then using the form method:
<form method="get" action="file.doc">
   <button type="submit">Download!</button>
</form>

endpoint: video starts to play in the same window

  1. Using href download attribute:
function download(url) {
  const a = document.createElement('a')
  a.href = url
  a.download = url.split('/').pop()
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}

endpoint: video starts to play in the same window

  1. Using your method:
const link = document.createElement('a')
link.href = url
link.click()

endpoint: video starts to play in the same windows

  1. With Axios defaults now:
  axios.defaults.withCredentials = true
     window.open(
       'https://cdn.pixaandom_urlrbay.com/vieo/487508532/Woman%20-%2058142.mp4?rendition=source&expiry=1666842719&hash=7dd6d178d9dbbd8adaf68dafd80c9167e91eca21&download'
     )

endpoint: video starts to play in the new window

  1. With attaching disposable content type in headers with AXIOS:
 axios
       .get(
         String(nuxtConfig.axios.mediaURL) +
           this.src_url.replace(
             'https://redisrandom_url.com/videos/',
             ''
           ),
         {
           headers: {
             mode: 'no-cors',
             referrerPolicy: 'no-referrer',
             'Content-Disposition': 'attachment; filename=Woman - 58142.mp4',
             Host: 'redis-nfs',
             'User-Agent': 'PostmanRuntime/7.29.2',
             Accept: '*/*',
             'Accept-Language': 'en-US,en;q=0.5',
             'Accept-Encoding': 'gzip, deflate, br',
             Connection: 'keep-alive',
             Cookie:
               'tk_or=%22https%3A%2F%2Fwww.google.com%2F%22; tk_lr=%22https%3A%2F%2Fwww.google.com%2F%22; _gcl_au=1.1.954672920.1660108804; _ga=GA1.2.1392122600.1660108808; _fbp=fb.1.1660108809200.1970395787',
             'Upgrade-Insecure-Requests': '1',
             'Sec-Fetch-Dest': 'document',
             'Sec-Fetch-Mode': 'navigate',
             'Sec-Fetch-Site': 'none',
             'Sec-Fetch-User': '?1',
             Pragma: 'no-cache',
             'Cache-Control': 'no-cache',
           },
         }
       )
       .then((response) => {
         console.log(response)

         const url = window.URL.createObjectURL(new Blob([response.data]))
         const link = document.createElement('a')
         link.href = url
         link.setAttribute('download', 'title')
         document.body.appendChild(link)
         link.click()
       })
       .catch((error) => {
         console.log('rex')
       })

endpoint: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at redis-random_url/videos/be319-72e1-2e79-8dc3-bcef1/…. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200

kissu
  • 40,416
  • 14
  • 65
  • 133
ash
  • 1,065
  • 1
  • 5
  • 20
  • 1
    I see a CORS issue at the end, hence give a try to that one at first: https://stackoverflow.com/a/72211930/8816585 – kissu Oct 27 '22 at 10:02
  • 1
    Also, it looks like you're using a service to download such video. I recommend that you check how the service wants you to download the video. You can also try [my technique](https://stackoverflow.com/a/67118753/8816585) with a simple and publicly available `.mp4` file hosted on a server somewhere (could be easily findable IMO). – kissu Oct 27 '22 at 10:04
  • It's publicly hosted and could be downloaded with Download Managers easily. I think I am failing at CORS. Right Now I am reading your great explanation of CORS. After that, I will try to compose a solution on that basis. – ash Oct 27 '22 at 10:08
  • 1
    Feel free to share an URL so that we can see here if it's public and easily downloadable. `https://cdn.pixaandom_urlrbay.com/vieo/487508532/Woman%20-%2058142.mp4?rendition=source&expiry=1666842719&hash=7dd6d178d9dbbd8adaf68dafd80c9167e91eca21&download` doesn't seem like something public since there is an expiry + hash. – kissu Oct 27 '22 at 10:36
  • 1
    First Of All Thankyou very very much @kissu. You are a great inspiration for kindness and knowledge. I run the chrome browser without security policies as mentioned in your method for CORS. It Downloads the File in vue with Ease. But now my goal is to make it versatile. So that it could download in normal browsers also. Again Thankyou very Much God Bless You. – ash Oct 27 '22 at 10:50

1 Answers1

1

"...But I am only able to download the link of the video, not the video."

I don't use VueJS but I suspect this.src_url is just text of the path to video URL.

In HTML5 you can only download those files that exist on your server. If the file is external then you need a PHP script (on same server as your HTML file) to read those external bytes back into your JS buffer array.

const blob = new Blob([this.src_url], { type: 'video/mp4' })

Should be:

let myBytes = //# update variable with data result of reading files bytes
let myBlob = new Blob(  [ Uint8Array.from( myBytes ) ] , {type: "application/octet-stream"} );

Where the bytes reading can be done with FileReader API or Fetch API.

When you can read a file's bytes into an Array using VueJS then your problem is solved.

VC.One
  • 14,790
  • 4
  • 25
  • 57
  • Thankyou very Much For spending your valuable time. And as I am using JavaScript. Not PHP and you provided the solution for it also. I will replicate the solution in way you expressed it. Actually this problem has multiple solution. As @kissu suggested with axios and related CORS headers could be solved with his beautiful explanation https://stackoverflow.com/a/72211930/17226535. One was to share link as content-disposable via Nginx as disposable attachment. And One could be also yours. I will implement your solution also. And Update, but tomorrow. #very-tired – ash Oct 27 '22 at 16:50