Advertisement
Advertisement


download file using an ajax request


Question

I want to send an "ajax download request" when I click on a button, so I tried in this way:

javascript:

var xhr = new XMLHttpRequest();
xhr.open("GET", "download.php");
xhr.send();

download.php:

<?
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename= file.txt");
header("Content-Transfer-Encoding: binary");    
readfile("file.txt");
?>

but doesn't work as expected, how can I do ? Thank you in advance

2013/12/29
1
95
12/29/2013 9:35:10 PM

Accepted Answer

Update April 27, 2015

Up and coming to the HTML5 scene is the download attribute. It's supported in Firefox and Chrome, and soon to come to IE11. Depending on your needs, you could use it instead of an AJAX request (or using window.location) so long as the file you want to download is on the same origin as your site.

You could always make the AJAX request/window.location a fallback by using some JavaScript to test if download is supported and if not, switching it to call window.location.

Original answer

You can't have an AJAX request open the download prompt since you physically have to navigate to the file to prompt for download. Instead, you could use a success function to navigate to download.php. This will open the download prompt but won't change the current page.

$.ajax({
    url: 'download.php',
    type: 'POST',
    success: function() {
        window.location = 'download.php';
    }
});

Even though this answers the question, it's better to just use window.location and avoid the AJAX request entirely.

2017/05/23
92
5/23/2017 11:47:25 AM

To make the browser downloads a file you need to make the request like that:

 function downloadFile(urlToSend) {
     var req = new XMLHttpRequest();
     req.open("GET", urlToSend, true);
     req.responseType = "blob";
     req.onload = function (event) {
         var blob = req.response;
         var fileName = req.getResponseHeader("fileName") //if you have the fileName header available
         var link=document.createElement('a');
         link.href=window.URL.createObjectURL(blob);
         link.download=fileName;
         link.click();
     };

     req.send();
 }
2017/03/15

You actually don't need ajax at all for this. If you just set "download.php" as the href on the button, or, if it's not a link use:

window.location = 'download.php';

The browser should recognise the binary download and not load the actual page but just serve the file as a download.

2014/04/23

Cross browser solution, tested on Chrome, Firefox, Edge, IE11.

In the DOM, add an hidden link tag:

<a id="target" style="display: none"></a>

Then:

var req = new XMLHttpRequest();
req.open("GET", downloadUrl, true);
req.responseType = "blob";
req.setRequestHeader('my-custom-header', 'custom-value'); // adding some headers (if needed)

req.onload = function (event) {
  var blob = req.response;
  var fileName = null;
  var contentType = req.getResponseHeader("content-type");

  // IE/EDGE seems not returning some response header
  if (req.getResponseHeader("content-disposition")) {
    var contentDisposition = req.getResponseHeader("content-disposition");
    fileName = contentDisposition.substring(contentDisposition.indexOf("=")+1);
  } else {
    fileName = "unnamed." + contentType.substring(contentType.indexOf("/")+1);
  }

  if (window.navigator.msSaveOrOpenBlob) {
    // Internet Explorer
    window.navigator.msSaveOrOpenBlob(new Blob([blob], {type: contentType}), fileName);
  } else {
    var el = document.getElementById("target");
    el.href = window.URL.createObjectURL(blob);
    el.download = fileName;
    el.click();
  }
};
req.send();
2019/11/20

It is possible. You can have the download started from inside an ajax function, for example, just after the .csv file is created.

I have an ajax function that exports a database of contacts to a .csv file, and just after it finishes, it automatically starts the .csv file download. So, after I get the responseText and everything is Ok, I redirect browser like this:

window.location="download.php?filename=export.csv";

My download.php file looks like this:

<?php

    $file = $_GET['filename'];

    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Disposition: attachment; filename=".$file."");
    header("Content-Transfer-Encoding: binary");
    header("Content-Type: binary/octet-stream");
    readfile($file);

?>

There is no page refresh whatsoever and the file automatically starts downloading.

NOTE - Tested in the following browsers:

Chrome v37.0.2062.120 
Firefox v32.0.1
Opera v12.17
Internet Explorer v11
2014/09/16

I prefer location.assign(url);

Complete syntax example:

document.location.assign('https://www.urltodocument.com/document.pdf');

developer.mozilla.org/en-US/docs/Web/API/Location.assign

2018/12/02