W
W
webmaster22017-05-12 17:41:24
JavaScript
webmaster2, 2017-05-12 17:41:24

How to implement file download via AJAX?

Hello
There is a web page with a form. When the button is clicked, data is sent to the server using jQuery.
The request code looks like this:

$.ajax({
            url : '/download-action',
            type : 'POST',           
            async : false,            
            beforeSend: function(xhr) {
                xhr.setRequestHeader('X-CSRF-TOKEN', $("#token").attr('value'));
            },
            data : JSON.stringify(sources),
            success : function(data) {
                
            }
        });

The data is sent to the server and processed. After processing, the server sends the file as follows (the code is written to the Laravel controller):
header("Pragma: public");
header("Content-Type: text/plain; charset=utf-8");
header("Content-Disposition: attachment; charset=utf-8; filename=\"file.txt\"");
header("Content-Transfer-Encoding: binary"); 
header("Content-Length: " . strlen($file_content));
echo $file_content;

When a response is received, plain text is returned. The file is not downloading.
Question:
How to correctly accept the file on the client side so that the download is performed?
Thanks in advance!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
E
Eugene Khrustalev, 2017-05-12
@webartisan2

Can't download file via AJAX. Dealt with this recently.
1. On the server, upon receiving an AJAX request, you can prepare a file and form a unique link to it, which you can send in response to the received AJAX request.
2. In the browser, having received a link to the file, open a new window

S
sokollondon, 2020-02-12
@sokollondon

How to download a file after receiving it via ajax
Convenient when the file takes a long time to create and you need to show the preloader
Example when submitting a web form

$(function () {
    $('form').submit(function () {
        $('#loader').show();
        $.ajax({
            url: $(this).attr('action'),
            data: $(this).serialize(),
            dataType: 'binary',
            xhrFields: {
                'responseType': 'blob'
            },
            success: function(data, status, xhr) {
                $('#loader').hide();
                // if(data.type.indexOf('text/html') != -1){//Если вместо файла получили страницу с ошибкой
                //     var reader = new FileReader();
                //     reader.readAsText(data);
                //     reader.onload = function() {alert(reader.result);};
                //     return;
                // }
                var link = document.createElement('a'),
                    filename = 'file.xlsx';
                // if(xhr.getResponseHeader('Content-Disposition')){//имя файла
                //     filename = xhr.getResponseHeader('Content-Disposition');
                //     filename=filename.match(/filename="(.*?)"/)[1];
                //     filename=decodeURIComponent(escape(filename));
                // }
                link.href = URL.createObjectURL(data);
                link.download = filename;
                link.click();
            }
        });
        return false;
    });
});

Optional functionality is commented out to simplify the example.
No need to create temporary files on the server.
Everything works on jQuery v2.2.4. On the old version there will be an error:
Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'blob').

https://stackoverflow.com/a/60185326/4831608

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question