Javascript 通过jquery ajax post下载文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28165424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Download file via jquery ajax post
提问by ????? ?????
I am trying to export my web page data and download it as excel file. but the download does not start even the response return succeed.
我正在尝试导出我的网页数据并将其下载为 excel 文件。但即使响应返回成功,下载也不会开始。
$.ajax({
type: "POST",
url: _url,
contentType: 'multipart/form-data;boundary=SzB12x',
data: json,
});
The responseText something like this:
responseText 是这样的:
PK?J;Fxl/theme/theme1.xml?YOo?6????,[r??n;v??i????#-?kJH:?oC{0X7?2??mZ???d??u@?(?b:M?????????{|??^?0t@??*"w$?!0I?[??n?i??'????iH? g?,??|?J?!???hRh?h???r&?L ????S??v@???#????"???}??Жt%?hR?t"??????+????????u{???0K???oy?9OTWywkA??
???F?? 6*?????[???U???
PK?J;Fxl/theme/theme1.xml?YOo?6? ???,[r??n;v??i??#-?kJH:?oC{0 X7?2??mZ ???d??u@?(?b:M?????????{|??^?0t@??*"w$? !0I?[??n?i??'????iH?g?,??|?J?!???hRh?h???r&?L ????S??v@? ??#????"???}??Жt%?hR?t"??????+??????? ???u{???0K???oy?9OTWywkA?? ???F?? 6*?????[???U???
I think its the file but I cant download it!!
我认为它的文件,但我不能下载它!
Any help please?
请问有什么帮助吗?
Thanks!
谢谢!
回答by Naren Yellavula
I faced the same issue and successfully solved it. My use-case is this.
我遇到了同样的问题并成功解决了它。我的用例是这样的。
- Post JSON data to server and receive an excel file.
- That excel file is created on the fly and returned as a response to client.
- 将 JSON 数据发布到服务器并接收一个 excel 文件。
- 该 excel 文件是即时创建的,并作为对客户端的响应返回。
Code:
代码:
$("#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));
});
The above snippet is just doing following
上面的代码片段只是在执行以下操作
- Posting an array as JSON to the server using XMLHttpRequest
- After fetching content as a blob(binary), we are creating a downloadable URL and attaching it to invisible "a" link then clicking it.
- 使用 XMLHttpRequest 将数组作为 JSON 发布到服务器
- 在将内容作为 blob(二进制)获取后,我们正在创建一个可下载的 URL 并将其附加到不可见的“a”链接,然后单击它。
Here we need to carefully set few things at the server side. I set few headers in Python Django HttpResponse. You need to set them accordingly if you are use other programming languages.
这里我们需要在服务器端仔细设置一些东西。我在 Python Django HttpResponse 中设置了几个标头。如果您使用其他编程语言,则需要相应地设置它们。
# In python django code
response = HttpResponse(file_content, content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
Since I download xls(excel) here, I adjusted contentType to above one. You need to set it according to your file type.
由于我在这里下载了 xls(excel),因此我将 contentType 调整为高于 1。您需要根据您的文件类型进行设置。
回答by mohammad
Try to use a hidden form to submit the request.
尝试使用隐藏表单提交请求。
When a user submits an HTML form, all the data entered into the form by the user is sent as either a GET or POST request to the URL specified in the “ACTION” attribute of FORM.
当用户提交 HTML 表单时,用户输入到表单中的所有数据都会作为 GET 或 POST 请求发送到 FORM 的“ACTION”属性中指定的 URL。
<FORM action="http://www.labnol.org/sendmail.php" method="post">
...form contents...
</FORM>
In the above example, an HTTP POST request is issued to the sendmail.php script on form submission. You can add target=”_blank” to the FORM tag to process the request in a new window.
在上面的示例中,在表单提交时向 sendmail.php 脚本发出 HTTP POST 请求。您可以在 FORM 标签中添加 target="_blank" 以在新窗口中处理请求。
However, if you would like to submit a FORM on the page in the background without directing the browser to another page (document.location.href changes on form submit), you have two options:
但是,如果您想在后台提交页面上的表单而不将浏览器定向到另一个页面(表单提交时 document.location.href 更改),您有两个选择:
Option #1. You can either create an invisible IFRAME inside your HTML page and set that as a target for the Original FORM. This will submit the form but without reloading the parent window.
选项1。您可以在 HTML 页面中创建一个不可见的 IFRAME,并将其设置为原始表单的目标。这将提交表单但不会重新加载父窗口。
<FORM action="http://example.com/script.php"
method="POST" target="hidden-form">
...form contents...
</FORM>
<IFRAME style="display:none" name="hidden-form"></IFRAME>
Option #2: There's another method that allows you create custom payloads before submitting the form. Unlike the IFRAME based form submission, the following code makes a standard form submit request and thus your browser location will change and the current page will get added to the browser history. Credit: Rakesh Pai.
选项#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_();
}
In thislink you can find the way to create hidden form and submit it.
在此链接中,您可以找到创建隐藏表单并提交的方法。
enjoy!!
请享用!!
回答by prototype
The approach here is directly lifted from https://gist.github.com/DavidMah/3533415.
这里的方法直接来自https://gist.github.com/DavidMah/3533415。
This approach uses <form>and appends the data with a key. This approach works if the server is already expecting the data as an attribute of the request body, as opposed to being the request body itself. If the data to be uploaded is an object, you could iterate over that object's keys. If the data to be uploaded is an array, either modify the server route or [add idea here].
这种方法使用<form>并附加一个键的数据。如果服务器已经将数据作为请求正文的属性,而不是作为请求正文本身,则此方法有效。如果要上传的数据是一个对象,您可以遍历该对象的键。如果要上传的数据是数组,要么修改服务器路由,要么[在此添加idea]。
In browser
在浏览器中
// 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();
};
On server
在服务器上
# 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
Example
例子
$.download('/path/resource/', 'data', JSON.stringify(data))
回答by Cà phê ?en
If you just want to download a file, you don't need to use ajax to do it. Actually, you cannot download file using ajax.
You can still do it by making a hyperlink <a href="your_link">Export</a>request to a server page that responses content-typeis application/vnd.ms-exceland content-dispositionis attachment.
如果你只是想下载一个文件,你不需要使用ajax来做。实际上,您无法使用 ajax 下载文件。
您仍然可以通过<a href="your_link">Export</a>向响应content-typeisapplication/vnd.ms-excel和content-dispositionis的服务器页面发出超链接请求来实现attachment。
回答by ozil
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: yoururlpath,
success: function (response) {
var file = fileName+".xlsx";
window.location = "someFilePath?file=" + file;
}
});
回答by Pramod Karandikar
You can achieve this using an iFrame as well. A sample function:
您也可以使用 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>"

