Force Download MP3 with Javascript

I’d like to download an mp3 file instead of playing /streaming it in Chrome. What I would like is for files to download automatically when users click on the links (i.e. a standard left click) and not via the “Save As” dialogue, but to the users default download folder for their browser.

Here is my approach, but could not achieve it successfully. I tried to download but nothing happened. Please help.

<a href="javascript:" onclick="saveAs(testinglink.mp3)">Download mp3</a>

<script>
function saveAs(url) {    
  var filename = url.substring(url.lastIndexOf("/") + 1).split("?")[0];
  var xhr = new XMLHttpRequest();
  xhr.responseType = 'blob';
  xhr.onload = function() {
    var a = document.createElement('a');
    a.href = window.URL.createObjectURL(xhr.response);
    a.download = filename; 
    a.style.display = 'none';
    document.body.appendChild(a);
    a.click();
    delete a;
  };
  xhr.open('GET', url);
  xhr.send();
}</script>

I don’t know the answer to that but I have a feeling what you are trying to do may not even be allowed by major browsers—it seems like the perfect way to tick off users and sounds like a security risk if a browser would just you let you bypass the “Save As” mechanism with JavaScript.

You cannot bypass that, since it’s a security feature to prevent malicious downloads. Only the user can set files to download automatically into a preferred folder.

If the browser has a valid MIME type for that file extension (mp3 in this case), a left click would cause the browser’s default action for that file. – in this case, playing it.

If you want a left-click to download the MP3 file instead, you need to create a “file handler” on the server side. Then on your webpage, you name your ahref links like this:

<a href="/downloadfile?file=londonCalling.mp3">Download</a>

Downloadfile above can be a php, or cshtml or asp, or whatever… as long as it can execute code on the server. Downloadfile will get the filename from the querystring url, read the contents of the file, and then send the file to the user as a stream. (Depending on server-side language you choose, the code below may differ) but take note of the headers, and ContentType that you’ll change.

      Response.AddHeader "Content-disposition", "filename=" & strFileName
      Response.ContentType = "application/octet-stream"
      Response.AddHeader "Pragma", "no-cache"
      Response.AddHeader "Expires", "0"

The key here is the new mime type “application/octet-stream” you’re assigning to the mp3 file, which is basically saying to the browser, hey here’s a binary file. Binary files are not viewable on a browser, so therefore the browser doesnt know what to do with it, and a prompt for “save” will popup. It’s up to the user to confirm, and click save button.

** Other stuff I didn’t mention **

For security reasons, you need to validate the file parameter the user wants to download. Don’t just automatically read the file and send it to the user. It’s a security risk. So validate the filename. That way, the user can’t enter whatever file they want (i.e. ?file=/path/to/yourpasswordfile) and only allow downloads of certain file extensions (i.e. don’t allow them to download the file index.php or default.cshtml) or some other file on the server.

Hope this helps.