Download file using jquery, generic handler and wait status
asp.net, c#, jquery
Solution
jQuery ajax is not able to handle binary responses properly (can't set responseType), so it's better to use a plain XMLHttpRequest call
var xhr = new XMLHttpRequest();
xhr.open('POST', "Handler1.ashx", true);
xhr.responseType = 'arraybuffer';
xhr.onload = function ()
{
if (this.status === 200)
{
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1)
{
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([this.response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined')
{
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
}
else
{
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename)
{
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined')
{
window.location = downloadUrl;
}
else
{
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
}
else
{
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
}
else
{
// Handle Error Here
}
};
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send($.param($(frm).serializeArray()));
}
You can get more help here :-)
Problem
Environment: .Net 3.5, jQuery 2.1.4 The result `Hello, World` comes back in the callback, but is there a way to make it come back as an attachment? jquery: ``` function test() { $.ajax({ type: "POST", url: "Handler1.ashx", contentType: "application/json; charset=utf-8", success: function (data) { $('#progressBar').hide(); //alert(data); } }); ``` generic handler: ``` public class Handler1 : IHttpHandler { public void ProcessRequest(HttpContext context) { //Create and populate a memorystream with the contents of the //database table System.IO.MemoryStream mstream = GetData(); //Convert the memorystream to an array of bytes. byte[] byteArray = mstream.ToArray(); //Clean up the memory stream mstream.Flush(); mstream.Close(); // Clear all content output from the buffer stream context.Response.Clear(); // Add a HTTP header to the output stream that specifies the default filename // for the browser's download dialog context.Response.AddHeader("Content-Disposition", "attachment; filename=mytextfile.txt"); // Add a HTTP header to the output stream that contains the // content length(File Size). This lets the browser know how much data is being transfered context.Response.AddHeader("Content-Length", byteArray.Length.ToString()); // Set the HTTP MIME type of the output stream context.Response.ContentType = "application/octet-stream"; // Write the data out to the client. context.Response.BinaryWrite(byteArray); } private MemoryStream GetData() { //Create the return memorystream object that will hold //the buffered data. MemoryStream ReturnStream = new MemoryStream(); try { Thread.Sleep(5000); //Simulate some work. StreamWriter sw = new StreamWriter(ReturnStream); //Write the row of data to the Memory Stream. sw.WriteLine("Hello, World"); //Clean up the stream writer sw.Flush(); sw.Close(); } catch (Exception Ex) { throw Ex; } //Return the memory Stream return ReturnStream; } public bool IsReusable { get { return false; } } } ``` Resources: http://www.c-sharpcorner.com/article/downloading-data-as-a-file-from-a-memorystream-using-a-http/