Downloading files from server responses is a common requirement in web applications. When using AJAX to send requests, handling file downloads can be tricky due to the nature of asynchronous requests. In this tutorial, we’ll explore how to handle file downloads from AJAX responses.
Understanding the Problem
When sending an AJAX request, the server response can contain various types of data, including JSON, XML, or even binary files. However, when dealing with file downloads, the server typically responds with a binary file and specific headers that indicate the file type and name. The challenge lies in handling this response on the client-side and providing a seamless download experience for the user.
Setting Up the Server-Side
To initiate a file download from an AJAX request, the server must respond with the correct headers. These headers include:
Content-Type
: specifies the MIME type of the fileContent-Disposition
: indicates that the response body should be saved as a file and provides the filenameCache-Control
: controls caching behavior
Here’s an example of setting these headers in PHP:
header("HTTP/1.1 200 OK");
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-type: application/octet-stream"); // replace with the actual MIME type
header("Content-Disposition: attachment; filename=\"example.txt\"");
Handling the Response Client-Side
To handle the file download on the client-side, we’ll use JavaScript and the XMLHttpRequest
object or a library like jQuery. When sending an AJAX request, set the responseType
property to 'blob'
to indicate that the response should be treated as binary data:
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = 'blob';
Alternatively, using jQuery:
$.ajax({
type: "POST",
url: url,
xhrFields: {
responseType: 'blob'
}
});
Triggering the Download
Once the response is received, we need to trigger the download. We can do this by creating a new Blob
object from the response data and using the URL.createObjectURL()
method to create a downloadable URL:
var blob = new Blob([response], { type: 'application/octet-stream' });
var url = window.URL || window.webkitURL;
var downloadUrl = url.createObjectURL(blob);
Next, we create an anchor element (<a>
) and set its href
attribute to the downloadable URL. We also set the download
attribute to specify the filename:
var a = document.createElement('a');
a.href = downloadUrl;
a.download = 'example.txt';
document.body.appendChild(a);
a.click();
Finally, we remove the anchor element and revoke the object URL to clean up:
setTimeout(function() {
url.revokeObjectURL(downloadUrl);
}, 100);
Example Code
Here’s a complete example using vanilla JavaScript:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://example.com/download', true);
xhr.responseType = 'blob';
xhr.onload = function() {
if (this.status === 200) {
var blob = this.response;
var url = window.URL || window.webkitURL;
var downloadUrl = url.createObjectURL(blob);
var a = document.createElement('a');
a.href = downloadUrl;
a.download = 'example.txt';
document.body.appendChild(a);
a.click();
setTimeout(function() {
url.revokeObjectURL(downloadUrl);
}, 100);
}
};
xhr.send();
And here’s an example using jQuery:
$.ajax({
type: "POST",
url: 'https://example.com/download',
xhrFields: {
responseType: 'blob'
},
success: function(blob) {
var url = window.URL || window.webkitURL;
var downloadUrl = url.createObjectURL(blob);
var a = document.createElement('a');
a.href = downloadUrl;
a.download = 'example.txt';
document.body.appendChild(a);
a.click();
setTimeout(function() {
url.revokeObjectURL(downloadUrl);
}, 100);
}
});
By following these steps, you can handle file downloads from AJAX responses and provide a seamless experience for your users.