Prompt file download with XMLHttpRequest

后端 未结 3 1929
清歌不尽
清歌不尽 2020-12-08 00:36

I\'m aware that jQuery\'s ajax method cannot handle downloads, and I do not want to add a jQuery plugin to do this.

I want to know how to send POST data with XMLHttp

3条回答
  •  猫巷女王i
    2020-12-08 01:30

    If you set the XMLHttpRequest.responseType property to 'blob' before sending the request, then when you get the response back, it will be represented as a blob. You can then save the blob to a temporary file and navigate to it.

    var postData = new FormData();
    postData.append('cells', JSON.stringify(output));
    
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/export/', true);
    xhr.setRequestHeader('X-CSRFToken', csrftoken);
    xhr.responseType = 'blob';
    xhr.onload = function (this, event) {
        var blob = this.response;
        var contentDispo = this.getResponseHeader('Content-Disposition');
        // https://stackoverflow.com/a/23054920/
        var fileName = contentDispo.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1];
        saveOrOpenBlob(blob, fileName);
    }
    xhr.send(postData);
    

    And here's an example implementation of saveOrOpenBlob:

    function saveOrOpenBlob(blob, fileName) {
        window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
        window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (fs) {
            fs.root.getFile(fileName, { create: true }, function (fileEntry) {
                fileEntry.createWriter(function (fileWriter) {
                    fileWriter.addEventListener("writeend", function () {
                        window.location = fileEntry.toURL();
                    }, false);
                    fileWriter.write(blob, "_blank");
                }, function () { });
            }, function () { });
        }, function () { });
    }
    

    If you don't care about having the browser navigate to the file when it's a viewable file type, then making a method that always saves directly to file is much simpler:

    function saveBlob(blob, fileName) {
        var a = document.createElement('a');
        a.href = window.URL.createObjectURL(blob);
        a.download = fileName;
        a.dispatchEvent(new MouseEvent('click'));
    }
    

提交回复
热议问题