通过jquery ajax post下载文件

时间:2015-01-27 07:37:18

标签: javascript jquery ajax multipartform-data

我正在尝试导出我的网页数据并将其下载为excel文件。但即使响应返回成功,下载也不会启动。

$.ajax({
      type: "POST",
      url: _url,
      contentType: 'multipart/form-data;boundary=SzB12x',
      data: json,
    });

responseText是这样的:

PKJ; FXL /主题/ theme1.xmlYOo6 ,[RN; 6#-kJH:OC {0 { {1} {MZ {1} {} |!^0吨@ *“W $ 0I [ni'iH g , | J ! hRh h ?r& L ߶S v@ # ׮ “ } Жt% HRT“+ ∪{ނ0Koy9OTWywkAͯ F 6* [ U

我认为它的文件但我无法下载!!

请帮忙吗?

谢谢!

6 个答案:

答案 0 :(得分:14)

我遇到了同样的问题并成功解决了它。我的用例就是这个。

  • 将JSON数据发布到服务器并接收excel文件。
  • 即时创建excel文件并作为对客户端的响应返回。

代码:

$("#my-button").on("click", function() {
    // Data to post
    data = {
        ids: [1, 2, 3, 4, 5]
    };

    // Use XMLHttpRequest instead of Jquery $ajax
    xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        var a;
        if (xhttp.readyState === 4 && xhttp.status === 200) {
            // Trick for making downloadable link
            a = document.createElement('a');
            a.href = window.URL.createObjectURL(xhttp.response);
            // Give filename you wish to download
            a.download = "test-file.xls";
            a.style.display = 'none';
            document.body.appendChild(a);
            a.click();
        }
    };
    // Post data to URL which handles post request
    xhttp.open("POST", excelDownloadUrl);
    xhttp.setRequestHeader("Content-Type", "application/json");
    // You should set responseType as blob for binary responses
    xhttp.responseType = 'blob';
    xhttp.send(JSON.stringify(data));
});

上面的代码片段正在执行以下操作

  • 使用XMLHttpRequest
  • 将数组作为JSON发布到服务器
  • 在将内容作为blob(二进制)获取后,我们创建了一个可下载的URL,并将其附加到不可见的“a”链接,然后单击它。

这里我们需要在服务器端仔细设置一些东西。我在Python Django HttpResponse中设置了几个标题。如果您使用其他编程语言,则需要相应地设置它们。

# In python django code
response = HttpResponse(file_content, content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")

由于我在这里下载xls(excel),我将contentType调整为高于1。您需要根据文件类型进行设置。

答案 1 :(得分:5)

尝试使用隐藏表单提交请求。

当用户提交HTML表单时,用户输入表单的所有数据都将作为GET或POST请求发送到FORM的“ACTION”属性中指定的URL。

 <FORM action="http://www.labnol.org/sendmail.php" method="post">
 ...form contents...
 </FORM>

在上面的示例中,在表单提交时向sendmail.php脚本发出HTTP POST请求。您可以将target =“_ blank”添加到FORM标记以在新窗口中处理请求。

但是,如果您想在后台页面上提交FORM而不将浏览器指向另一个页面(document.location.href更改表单提交),您有两个选择:

选项#1。您可以在HTML页面中创建一个不可见的IFRAME,并将其设置为原始FORM的目标。这将提交表单,但不会重新加载父窗口。

<FORM action="http://example.com/script.php" 
           method="POST" target="hidden-form">
 ...form contents... 
 </FORM>
<IFRAME style="display:none" name="hidden-form"></IFRAME> 

选项#2:还有另一种方法可以在提交表单之前创建自定义有效负载。与基于IFRAME的表单提交不同,以下代码生成标准表单提交请求,因此您的浏览器位置将更改,并且当前页面将添加到浏览器历史记录中。图片来源:Rakesh Pai。

submitFORM('http://example.com/script.php', 'POST',
    {'name':'digital+inspiration', 'age':'100', 'sex','M'});

function submitFORM(path, params, method) {
    method = method || "post"; 

    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    //Move the submit function to another variable
    //so that it doesn't get overwritten.
    form._submit_function_ = form.submit;

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
         }
    }

    document.body.appendChild(form);
    form._submit_function_();
}

this链接中,您可以找到创建隐藏表单并提交的方法。

享受!!

答案 2 :(得分:2)

这里的方法直接取决于DateTimeFormatter

此方法使用// Takes a URL, param name, and data string // Sends to the server... The server can respond with binary data to download jQuery.download = function(url, key, data) { // Build a form var form = $('<form></form>').attr('action', url).attr('method', 'post'); // Add the one key/value form.append($("<input></input>").attr('type', 'hidden').attr('name', key).attr('value', data)); //send request form.appendTo('body').submit().remove(); }; 并使用密钥附加数据。如果服务器已经将数据作为请求主体的属性,而不是请求主体本身,则此方法有效。如果要上载的数据是对象,则可以迭代该对象的键。如果要上载的数据是数组,请修改服务器路由或[在此处添加想法]。

在浏览器中

# A Tidbit of sinatra code to respond
# Assume 'url' is a set variable
# Assume 'key' is the key of the value used in the javascript

post url do
  data = params[:key]
  puts request.body.read
  headers['Content-Type'] = "application/octet-stream"

  body(data)
end

在服务器上

$.download('/path/resource/', 'data', JSON.stringify(data))

实施例

{{1}}

答案 3 :(得分:1)

如果您只想下载文件,则无需使用ajax即可。实际上,您无法使用ajax下载文件 您仍然可以通过向服务器页面发送超链接<a href="your_link">Export</a>请求来执行此操作,其中响应content-typeapplication/vnd.ms-excelcontent-dispositionattachment

答案 4 :(得分:-1)

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: yoururlpath,
    success: function (response) {
        var file = fileName+".xlsx";
        window.location = "someFilePath?file=" + file;
    }
});

答案 5 :(得分:-2)

您也可以使用iFrame实现此目的。示例函数:

// append the data to URL
var requestData = {
    param1 : "value1",
    param2 : "value2",
}

// call the function
downloadFile(<your_URL>, requestData);

function downloadFile(requestURL, data) {
    // "transData" is just a user defined variable to encapsulate "downloadIFrame". It can be named anything as required.
    var downloadIFrame = window.transData.downloadIFrame = window.transData.downloadIFrame || $("#downloadFileiFrame");
    downloadIFrame.attr("src", requestURL + $.param(requestData));
}

// define the iFrame in your HTML and hide it.
<iframe id="downloadFileiFrame" style="display:none;"></iframe>"