501 Stimmen

Herunterladen einer Datei mit jQuery.Ajax

Ich habe eine Struts2-Aktion auf der Serverseite zum Herunterladen von Dateien.

<action name="download" class="com.xxx.DownAction">
    <result name="success" type="stream">
        <param name="contentType">text/plain</param>
        <param name="inputName">imageStream</param>
        <param name="contentDisposition">attachment;filename={fileName}</param>
        <param name="bufferSize">1024</param>
    </result>
</action>

Wenn ich jedoch die Aktion mit dem jQuery:

$.post(
  "/download.action",{
    para1:value1,
    para2:value2
    ....
  },function(data){
      console.info(data);
   }
);

in Firebug sehe ich, dass die Daten mit der Binärer Strom . Ich frage mich, wie man die Fenster zum Herunterladen von Dateien mit der der Benutzer die Datei lokal speichern kann?

8voto

Shahrukh Alam Punkte 41

Der HTML-Code :

<button type="button" id="GetFile">Get File!</button>

Der jQuery-Code :

$('#GetFile').on('click', function () {
    $.ajax({
        url: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/172905/test.pdf',
        method: 'GET',
        xhrFields: {
            responseType: 'blob'
        },
        success: function (data) {
            var a = document.createElement('a');
            var url = window.URL.createObjectURL(data);
            a.href = url;
            a.download = 'myfile.pdf';
            document.body.append(a);
            a.click();
            a.remove();
            window.URL.revokeObjectURL(url);
        }
    });
});

6voto

Mike S Punkte 182

Wie man eine Datei herunterlädt, nachdem man sie per AJAX empfangen hat

Es ist praktisch, wenn die Datei lange erstellt wird und Sie PRELOADER anzeigen müssen

Beispiel beim Absenden eines Webformulars:

<script>
$(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){//If instead of a file you get an error page
                //     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 
                //     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;
    });
});
</script>

Zur Vereinfachung des Beispiels wird die optionale Funktion auskommentiert.

Es müssen keine temporären Dateien auf dem Server angelegt werden.

Bei jQuery v2.2.4 OK. Bei der alten Version wird ein Fehler auftreten:

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').

5voto

kyakya Punkte 1719

Ich versuche, eine CSV-Datei herunterzuladen und dann etwas zu tun, nachdem der Download beendet ist. Ich muss also eine entsprechende callback Funktion.

Verwendung von window.location="..." ist keine gute Idee, da ich das Programm nach Abschluss des Downloads nicht mehr bedienen kann. So etwas wie diese, ändern Sie die Kopfzeile, so dass es keine gute Idee ist.

fetch ist jedoch eine gute Alternative er kann den IE 11 nicht unterstützen . Und window.URL.createObjectURL kann IE 11 nicht unterstützen. Sie können este .

Dies ist mein Code, er ähnelt dem Code von Shahrukh Alam. Aber Sie sollten darauf achten, dass window.URL.createObjectURL möglicherweise Speicherlecks verursachen. Sie können auf este . Sobald die Antwort eingetroffen ist, werden die Daten im Speicher des Browsers abgelegt. Bevor Sie also klicken a Link, die Datei wurde heruntergeladen. Das bedeutet, dass Sie nach dem Herunterladen alles tun können.

$.ajax({
    url: 'your download url',
    type: 'GET',
}).done(function (data, textStatus, request) {
    // csv => Blob
    var blob = new Blob([data]);

    // the file name from server.
    var fileName = request.getResponseHeader('fileName');

    if (window.navigator && window.navigator.msSaveOrOpenBlob) { // for IE
    window.navigator.msSaveOrOpenBlob(blob, fileName);
    } else { // for others
    var url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    a.download = fileName;
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);

    //Do something after download 
    ...

    }
}).then(after_download)
}

5voto

EL missaoui habib Punkte 1047
function downloadURI(uri, name) 
{
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
}

4voto

aarkerio Punkte 1891

In Rails mache ich das so:

function download_file(file_id) {
  let url       = '/files/' + file_id + '/download_file';
    $.ajax({
    type: 'GET',
    url: url,
    processData: false,
    success: function (data) {
       window.location = url;
    },
    error: function (xhr) {
     console.log(' Error:  >>>> ' + JSON.stringify(xhr));
    }
   });
 }

Der Trick ist die fenster.standort Teil. Die Methode des Controllers sieht wie folgt aus:

# GET /files/{:id}/download_file/
def download_file
    send_file(@file.file,
          :disposition => 'attachment',
          :url_based_filename => false)
end

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X