Why threre is no way to download file using ajax r

2019-01-03 10:20发布

In our application we need to implement following scenario:

  1. A request is send from client
  2. Server handles the request and generates file
  3. Server returns file in response
  4. Client browser displays file download popup dialog and allows user to download the file

Our application is ajax based application, so it would be very easy and convenient for us to send ajax request (like using jquery.ajax() function).

But after googilng, it turned out that file downloading is possible only when using non-ajax POST request (like described in this popular SO thread). So we needed to implement uglier and more complex solution that required building HTML structure of form with nested hidden fields.

Could someone explain in simple words why is that ajax requests cannot be used to download file? What's the mechanics behind that?

4条回答
贼婆χ
2楼-- · 2019-01-03 10:39

That's the same question I'd asked myself two days ago. There was a project with client written using ExtJS and server side realisation was on ASP.Net. I have to translate server side to Java. There was a function to download an XML file, that server generates after Ajax request from the client. We all know, that it's impossible to download file after Ajax request, just to store it in memory. But ... in the original application browser shows usual dialog with options open, save and cancel downloading. ASP.Net somehow changed the standard behaviour... It takes me two day to to prove again - there is no way to download file by request usual way ... the only exception is ASP.Net... Here is ASP.Net code

public static void WriteFileToResponse(byte[] fileData, string fileName)
    {
        var response = HttpContext.Current.Response;

        var returnFilename = Path.GetFileName(fileName);
        var headerValue = String.Format("attachment; filename={0}", 
            HttpUtility.UrlPathEncode(
                String.IsNullOrEmpty(returnFilename) 
                    ? "attachment" : returnFilename));
        response.AddHeader("content-disposition", headerValue);
        response.ContentType = "application/octet-stream";
        response.AddHeader("Pragma", "public");

        var utf8 = Encoding.UTF8;
        response.Charset = utf8.HeaderName;
        response.ContentEncoding = utf8;
        response.Flush();
        response.BinaryWrite(fileData);
        response.Flush();
        response.Close();
    }

This method was called from WebMethod, that, in turn, was called from ExtJS.Ajax.request. That's the magic. What's to me, I've ended with servlet and hidden iframe...

查看更多
三岁会撩人
3楼-- · 2019-01-03 10:49

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.

查看更多
时光不老,我们不散
4楼-- · 2019-01-03 10:58

you can do this by using hidden iframe in your download page

just set the src of the hidden ifame in your ajax success responce and your task is done...

  $.ajax({
        type: 'GET',
        url: './page.php',
        data: $("#myform").serialize(),
        success: function (data) {
          $("#middle").attr('src','url');
        },

});
查看更多
神经病院院长
5楼-- · 2019-01-03 11:00

This can be done using the new HTML5 feature called Blob. There is a library FileSaver.js that can be utilized as a wrapper on top of that feature.

查看更多
登录 后发表回答