Download File Using an Ajax Request

download file using an ajax request

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.

Download a file by jQuery.Ajax

2019 modern browsers update

This is the approach I'd now recommend with a few caveats:

  • A relatively modern browser is required
  • If the file is expected to be very large you should likely do something similar to the original approach (iframe and cookie) because some of the below operations could likely consume system memory at least as large as the file being downloaded and/or other interesting CPU side effects.

fetch('https://jsonplaceholder.typicode.com/todos/1')  .then(resp => resp.blob())  .then(blob => {    const url = window.URL.createObjectURL(blob);    const a = document.createElement('a');    a.style.display = 'none';    a.href = url;    // the filename you want    a.download = 'todo-1.json';    document.body.appendChild(a);    a.click();    window.URL.revokeObjectURL(url);    alert('your file has downloaded!'); // or you know, something with better UX...  })  .catch(() => alert('oh no!'));

Why threre is no way to download file using ajax request?

It's not about AJAX. You can download a file with AJAX, of course. However the file will be kept in memory, i.e. you cannot save file to disk. This is because JavaScript cannot interact with disk. That would be a serious security issue and it is blocked in all major browsers.

Download a file through ajax request in asp.net MVC

You should know that AJAX call is not intended to download CSV file directly. Therefore, you can create a byte array from MemoryStream instance and store it inside Session or TempData variable, then return 'successful' state to enable redirect on AJAX success response:

public ActionResult GetHistoricalUsageApplicationFile([DataSourceRequest]DataSourceRequest request, [FromBody] string accountCodes)
{
var HistoricalUsagesData = _enrollmentManagementRepository.GetHistoricalUsageApplicationFile(accountCodes);
List<HistoricalUsageApplicationFileModel> HUApplications = _mapper.MapToNew<List<HistoricalUsageApplicationFileModel>>(HistoricalUsagesData);
//var HistoricalUsageApplication = HUReport.ToDataSourceResult(request).Data;

var output = new MemoryStream();
var writer = new StreamWriter(output, Encoding.UTF8);

writer.Write("CommodityCode,");
writer.Write("CustomerTypeCode,");
writer.Write("EnrollmentRequestId");
writer.WriteLine();

var list = HUApplications.ConvertToString();
var single = list.Aggregate((x, y) => { return string.Concat(x, y); });

writer.WriteAsync(single);
writer.Flush();
output.Position = 0;

// creates byte array from stream
TempData["Output"] = output.ToArray();

// returns successful state
return Json("Success", JsonRequestBehavior.AllowGet);
}

Second, create a controller action with GET method and pass stored byte array from Session or TempData into FileResult:

public ActionResult DownloadCSV()
{
// retrieve byte array here
var array = TempData["Output"] as byte[];
if (array != null)
{
return File(array, System.Net.Mime.MediaTypeNames.Application.Octet, "Products.csv");
}
else
{
return new EmptyResult();
}
}

Finally, handle success response to include location.href which will redirect to controller returning FileResult to download CSV file:

$.ajax({
url: '@Url.Action("GetHistoricalUsageApplicationFile", "HUProducts")',
type: 'GET',
data: { "accountCodes": strAccountCodes },
success: function (result) {
if (result == "Success") {
location.href = '@Url.Action("DownloadCSV", "ControllerName")';
}
}
});

As an option, you could pass CSV file name as parameter from AJAX response using query string.

Related issue:

Creating a byte array from a stream

How to download a file through ajax request in asp.net MVC 4

Please, try this in ajax success

success: function () {
window.location = '@Url.Action("DownloadAttachment", "PostDetail")';
}

Updated answer:

public ActionResult DownloadAttachment(int studentId)
{
// Find user by passed id
// Student student = db.Students.FirstOrDefault(s => s.Id == studentId);

var file = db.EmailAttachmentReceived.FirstOrDefault(x => x.LisaId == studentId);

byte[] fileBytes = System.IO.File.ReadAllBytes(file.Filepath);

return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, file.Filename);

}

Ajax request:

$(function () {
$("#DownloadAttachment").click(function () {
$.ajax(
{
url: '@Url.Action("DownloadAttachment", "PostDetail")',
contentType: 'application/json; charset=utf-8',
datatype: 'json',
data: {
studentId: 123
},
type: "GET",
success: function () {
window.location = '@Url.Action("DownloadAttachment", "PostDetail", new { studentId = 123 })';
}
});

});
});

File download through ajax

Don't make an AJAX call, but rather set the window's href to point to URL for downloading the file. Then change the content type of the response to application/x-download and set the header of the response to be Content-disposition:

response.setContentType("application/x-download");
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
response.flushBuffer();

function download(fileName) {
window.location.href = "/download?description=test&logId=123";
}

Also, have a look at this SO post which addresses a similar problem to the one you have.

Handle file download from ajax post

Create a form, use the POST method, submit the form - there's no need for an iframe. When the server page responds to the request, write a response header for the mime type of the file, and it will present a download dialog - I've done this a number of times.

You want content-type of application/download - just search for how to provide a download for whatever language you're using.

downloaded data file from ajax

Modern browsers support the download attribute for the <a> tag.

This attribute, if present, indicates that the author intends the hyperlink to be used for downloading a resource so that when the user clicks on the link they will be prompted to save it as a local file. If the attribute has a value, the value will be used as the pre-filled file name in the Save prompt that opens when the user clicks on the link (the user can change the name before actually saving the file of course). There are no restrictions on allowed values (though / and \ will be converted to underscores, preventing specific path hints), but you should consider that most file systems have limitations with regard to what punctuation is supported in file names, and browsers are likely to adjust file names accordingly.

Note:
Can be used with blob: URLs and data: URLs, to make it easy for users to download content that is generated programmatically using JavaScript (e.g. a picture created using an online drawing Web app).
If the HTTP header Content-Disposition: is present and gives a different filename than this attribute, the HTTP header has priority over this attribute.
If this attribute is present and Content-Disposition: is set to inline, Firefox gives priority to Content-Disposition, like for the filename case, while Chrome gives priority to the download attribute.
This attribute is only honored for links to resources with the same-origin.

<a download src="restAPI/file.pdf">Download File</a>

So when you click the a tag it will show a popup that will download the file. From the request I can see that the file is already available.

You can read about it more : https://developer.mozilla.org/en/docs/Web/HTML/Element/a



Related Topics



Leave a reply



Submit