Download file from ajax and ActionResult

2020-04-16 18:32发布

I want to download files on browser with ajax and ActionResult. The file is downloaded and returned from my ActionResult.

I see the Http query is ok and see the data in the response body. The problem is that the file is not proposed to save in the browser.

All seems good. All that I seen in tutorial and forum were like I done but mine don't word XD. I don't understand what is the difference between mine and the others.

Here is my ActionResult :

public ActionResult ShippingDownloadDNPriority(string SALE_GUID)
{
    int supId = -1;
    int.TryParse(Session["SupId"].ToString(), out supId);
    if (supId < 0)
        return null;

    WebResponse response = CallApi.DownloadAndCreateDN(Session["UserLogin"].ToString(), Session["IdentConnect"].ToString(), SALE_GUID, supId, true);
    Stream responseStream = response.GetResponseStream();

    var cd = new System.Net.Mime.ContentDisposition
    {
        FileName = "myfile.pdf",
        Inline = false,
    };
    Response.Headers.Add("Content-Disposition", cd.ToString());
    Response.ContentType = "application/octet-stream";
    return File(responseStream, System.Net.Mime.MediaTypeNames.Application.Pdf, "myfile.pdf");
}

public static WebResponse DownloadAndCreateDN(string login, string session, string SALE_GUID, int supid, bool priority)
{
    string[] res = new string[2];

    StringBuilder postData = new StringBuilder();
    postData.AppendLine("{");
    postData.AppendLine(string.Format("\"login\":\"{0}\",", login));
    postData.AppendLine(string.Format("\"session\":\"{0}\",", session));
    postData.AppendLine(string.Format("\"saleguid\":\"{0}\",", SALE_GUID));
    postData.AppendLine(string.Format("\"supid\":{0},", supid));
    postData.AppendLine(string.Format("\"prority\":{0}", priority.ToString().ToLower()));
    postData.AppendLine("}");

    ASCIIEncoding ascii = new ASCIIEncoding();
    byte[] postBytes = ascii.GetBytes(postData.ToString());

    string url = Properties.Settings.Default.ISAPIAddress + "deliverynote/create";

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/json";
    request.ContentLength = postBytes.Length;

    Stream postStream = request.GetRequestStream();
    postStream.Write(postBytes, 0, postBytes.Length);
    postStream.Flush();
    postStream.Close();

    return request.GetResponse();
}

Here is my javascript :

$.ajax({
    url: '../Shipping/ShippingDownloadDNPriority?SALE_GUID=XXXXXXXXXXXXXX',
    data: { SALE_GUID: DropShipping.GetRowKey(rowIndexSale) },
    async: false,
    //success: function (data) { window.downloadFile = data; }
});

Thanks all

2条回答
你好瞎i
2楼-- · 2020-04-16 19:13

I changed of idea. I simply send my pdf (from my controller) in 64 base and make in the ajax :

success: function (data) {
     window.open("data:application/pdf;base64," + data.data, '_blank'); 
}
查看更多
你好瞎i
3楼-- · 2020-04-16 19:27

AJAX is just a thin client. Nothing happens with the response returned by default. You are responsible to making the download happen. However, doing that requires the File API that's part of HTML5. As a result, this is only possible in modern browsers (IE10+).

Inside your AJAX success method:

var blob = new Blob(data, { type: 'application/pdf' });
var a = document.createElement('a');
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = 'myfile.pdf';
a.click();
window.URL.revokeObjectURL(url);

EDIT

jQuery doesn't interpret the response type correctly by default. You'll need to modify your $.ajax call slightly:

$.ajax({
    url: '../Shipping/ShippingDownloadDNPriority?SALE_GUID=XXXXXXXXXXXXXX',
    data: { SALE_GUID: DropShipping.GetRowKey(rowIndexSale) },
    async: false,
    // -- ADD THIS --
    xhrFields: {
        responseType: 'blob'
    },
    success: function (data) {
        // code above here, but no longer need to create blob
        var a = document.createElement('a');
        var url = window.URL.createObjectURL(data);
        a.href = url;
        a.download = 'myfile.pdf';
        a.click();
        window.URL.revokeObjectURL(url);
    }
});

You can check out a CodePen here to see it working.

查看更多
登录 后发表回答