[英]Download a file by jQuery.Ajax
我在服务器端有一个 Struts2 操作用于文件下载。
<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>
但是,当我使用 jQuery 调用操作时:
$.post(
"/download.action",{
para1:value1,
para2:value2
....
},function(data){
console.info(data);
}
);
在 Firebug 中,我看到使用二进制 stream检索数据。 我想知道如何打开下载window的文件,用户可以用它在本地保存文件?
2019 年现代浏览器更新
这是我现在推荐的方法,但有一些注意事项:
fetch('https://jsonplaceholder.typicode.com/todos/1') .then(resp => resp.blob()) .then(blob => { const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; // the filename you want a.download = 'todo-1.json'; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); alert('your file has downloaded!'); // or you know, something with better UX... }) .catch(() => alert('oh no!'));
2012 原始的基于 jQuery/iframe/Cookie 的方法
Bluish在这点上是完全正确的,你不能通过 Ajax 来做到这一点,因为 JavaScript 不能将文件直接保存到用户的计算机上(出于安全考虑)。 不幸的是,将主窗口的URL 指向您的文件下载意味着您几乎无法控制文件下载发生时的用户体验。
我创建了jQuery File Download ,它允许通过 OnSuccess 和 OnFailure 回调完成文件下载的“类似 Ajax”体验,以提供更好的用户体验。 看看我关于插件解决的常见问题的博客文章和一些使用它的方法,还有一个jQuery File Download in action 的演示。 这里是源
这是一个使用带有 Promise 的插件源的简单用例演示。 演示页面还包括许多其他“更好的 UX”示例。
$.fileDownload('some/file.pdf')
.done(function () { alert('File download a success!'); })
.fail(function () { alert('File download failed!'); });
根据您需要支持的浏览器,您可以使用https://github.com/eligrey/FileSaver.js/ ,它允许比 jQuery File Download 使用的 IFRAME 方法更明确的控制。
没有人发布这个@Pekka 的解决方案......所以我会发布它。 它可以帮助某人。
您不需要通过 Ajax 执行此操作。 只需使用
window.location="download.action?para1=value1...."
您可以使用 HTML5
注意:返回的文件数据必须是 base64 编码,因为您不能 JSON 编码二进制数据
在我的AJAX
响应中,我有一个如下所示的数据结构:
{
result: 'OK',
download: {
mimetype: string(mimetype in the form 'major/minor'),
filename: string(the name of the file to download),
data: base64(the binary data as base64 to download)
}
}
这意味着我可以执行以下操作以通过 AJAX 保存文件
var a = document.createElement('a');
if (window.URL && window.Blob && ('download' in a) && window.atob) {
// Do it the HTML5 compliant way
var blob = base64ToBlob(result.download.data, result.download.mimetype);
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = result.download.filename;
a.click();
window.URL.revokeObjectURL(url);
}
函数 base64ToBlob 取自这里,必须按照此函数使用
function base64ToBlob(base64, mimetype, slicesize) {
if (!window.atob || !window.Uint8Array) {
// The current browser doesn't have the atob function. Cannot continue
return null;
}
mimetype = mimetype || '';
slicesize = slicesize || 512;
var bytechars = atob(base64);
var bytearrays = [];
for (var offset = 0; offset < bytechars.length; offset += slicesize) {
var slice = bytechars.slice(offset, offset + slicesize);
var bytenums = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
bytenums[i] = slice.charCodeAt(i);
}
var bytearray = new Uint8Array(bytenums);
bytearrays[bytearrays.length] = bytearray;
}
return new Blob(bytearrays, {type: mimetype});
};
如果您的服务器正在转储要保存的文件数据,这很好。 但是,我还没有完全弄清楚如何实现 HTML4 后备
让浏览器下载文件的简单方法是发出这样的请求:
function downloadFile(urlToSend) {
var req = new XMLHttpRequest();
req.open("GET", urlToSend, true);
req.responseType = "blob";
req.onload = function (event) {
var blob = req.response;
var fileName = req.getResponseHeader("fileName") //if you have the fileName header available
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download=fileName;
link.click();
};
req.send();
}
这将打开浏览器下载弹出窗口。
1. 与框架无关:Servlet 下载文件作为附件<\/strong>
<!-- with JS -->
<a href="javascript:window.location='downloadServlet?param1=value1'">
download
</a>
<!-- without JS -->
<a href="downloadServlet?param1=value1" >download</a>
我创建了一个小功能作为解决方案(受@JohnCulviner 插件的启发):
// creates iframe and form in it with hidden field,
// then submit form with provided data
// url - form url
// data - data to form field
// input_name - form hidden input name
function ajax_download(url, data, input_name) {
var $iframe,
iframe_doc,
iframe_html;
if (($iframe = $('#download_iframe')).length === 0) {
$iframe = $("<iframe id='download_iframe'" +
" style='display: none' src='about:blank'></iframe>"
).appendTo("body");
}
iframe_doc = $iframe[0].contentWindow || $iframe[0].contentDocument;
if (iframe_doc.document) {
iframe_doc = iframe_doc.document;
}
iframe_html = "<html><head></head><body><form method='POST' action='" +
url +"'>" +
"<input type=hidden name='" + input_name + "' value='" +
JSON.stringify(data) +"'/></form>" +
"</body></html>";
iframe_doc.open();
iframe_doc.write(iframe_html);
$(iframe_doc).find('form').submit();
}
带有点击事件的演示:
$('#someid').on('click', function() {
ajax_download('/download.action', {'para1': 1, 'para2': 2}, 'dataname');
});
我遇到了同样的问题并成功解决了。 我的用例是这样的。
" “ 将”
$("#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));
});
好的,基于 ndpu 的代码继承了 ajax_download 的改进(我认为)版本;-
function ajax_download(url, data) {
var $iframe,
iframe_doc,
iframe_html;
if (($iframe = $('#download_iframe')).length === 0) {
$iframe = $("<iframe id='download_iframe'" +
" style='display: none' src='about:blank'></iframe>"
).appendTo("body");
}
iframe_doc = $iframe[0].contentWindow || $iframe[0].contentDocument;
if (iframe_doc.document) {
iframe_doc = iframe_doc.document;
}
iframe_html = "<html><head></head><body><form method='POST' action='" +
url +"'>"
Object.keys(data).forEach(function(key){
iframe_html += "<input type='hidden' name='"+key+"' value='"+data[key]+"'>";
});
iframe_html +="</form></body></html>";
iframe_doc.open();
iframe_doc.write(iframe_html);
$(iframe_doc).find('form').submit();
}
这是我所做的,纯 javascript 和 html。 没有测试它,但这应该适用于所有浏览器。
Javascript 函数
var iframe = document.createElement('iframe');
iframe.id = "IFRAMEID";
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.src = 'SERVERURL'+'?' + $.param($scope.filtro);
iframe.addEventListener("load", function () {
console.log("FILE LOAD DONE.. Download should start now");
});
仅使用所有浏览器都支持的组件,无需额外的库。
这是我的服务器端 JAVA Spring 控制器代码。
@RequestMapping(value = "/rootto/my/xlsx", method = RequestMethod.GET)
public void downloadExcelFile(@RequestParam(value = "param1", required = false) String param1,
HttpServletRequest request, HttpServletResponse response)
throws ParseException {
Workbook wb = service.getWorkbook(param1);
if (wb != null) {
try {
String fileName = "myfile_" + sdf.format(new Date());
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + ".xlsx\"");
wb.write(response.getOutputStream());
response.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
通过 AJAX 接收文件后如何下载文件
文件创建时间长需要显示PRELOADER时很方便
提交 Web 表单时的示例:
<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>
注释掉可选功能以简化示例。
无需在服务器上创建临时文件。
在 jQuery v2.2.4 上可以。 老版本会报错:
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').
function downloadURI(uri, name)
{
var link = document.createElement("a");
link.download = name;
link.href = uri;
link.click();
}
我尝试下载 CSV 文件,然后在下载完成后执行某些操作。 所以我需要实现一个合适的
callback<\/code>函数。
使用
window.location="..."<\/code>不是一个好主意,因为我在完成下载后无法操作该程序。
像这样的东西,改变标题所以这不是一个好主意。
fetch<\/code>是一个不错的选择,但
它不支持 IE 11<\/a> 。
而
window.URL.createObjectURL<\/code>不支持IE
window.URL.createObjectURL<\/code>你可以参考
这个<\/a>。
这是我的代码,它类似于 Shahrukh Alam 的代码。 但是您应该注意
window.URL.createObjectURL<\/code>可能会造成内存泄漏。
你可以参考这个<\/a>。 当响应到达时,数据将被存储到浏览器的内存中。
所以,你点击之前
a<\/code>链接,该文件已被下载。
这意味着您可以在下载后进行任何操作。
$.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)
}
我的方法完全基于 jQuery。 我的问题是它必须是一个 POST-HTTP 调用。 我希望它由 jQuery 单独完成。
解决方案:
$.ajax({
type: "POST",
url: "/some/webpage",
headers: {'X-CSRF-TOKEN': csrfToken},
data: additionalDataToSend,
dataType: "text",
success: function(result) {
let blob = new Blob([result], { type: "application/octetstream" });
let a = document.createElement('a');
a.href = window.URL.createObjectURL(blob);
a.download = "test.xml";;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(a.href);
...
},
error: errorDialog
});
解释:
我和许多其他人所做的是在网页上创建一个链接,指示应该下载目标并将 http-request 的结果作为目标。 之后,我将链接附加到文档,而不是简单地单击链接并随后删除链接。 您不再需要 iframe。
神奇在于线条
let blob = new Blob([result], { type: "application/octetstream" });
a.href = window.URL.createObjectURL(blob);
有趣的是,这个解决方案只适用于“ blob ”。 正如您在其他答案中看到的那样,有些人只是使用 blob,但没有解释为什么以及如何创建它。 正如您可以在Mozilla 开发人员文档中看到的那样,您需要一个文件、媒体资源或 blob 才能使函数“ createObjectURL() ”工作。 问题是您的 http-response 可能不是其中的任何一个。 因此,您必须做的第一件事是将响应转换为 blob。 这就是第一行的作用。 然后,您可以将“ createObjectURL ”与新创建的 blob 一起使用。 如果您单击该链接,您的浏览器将打开一个文件保存对话框,您可以保存您的数据。 显然,您可能无法为要下载的文件定义一个固定的文件名。 然后你必须让你的回答更复杂,就像卢克的回答一样。
并且不要忘记释放内存,尤其是在处理大文件时。 有关更多示例和信息,您可以查看JS blob 对象的详细信息
在上面的答案中添加更多内容以下载文件
下面是一些生成字节数组的java spring代码
@RequestMapping(value = "/downloadReport", method = { RequestMethod.POST })
public ResponseEntity<byte[]> downloadReport(
@RequestBody final SomeObejct obj, HttpServletResponse response) throws Exception {
OutputStream out = new ByteArrayOutputStream();
// write something to output stream
HttpHeaders respHeaders = new HttpHeaders();
respHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
respHeaders.add("X-File-Name", name);
ByteArrayOutputStream bos = (ByteArrayOutputStream) out;
return new ResponseEntity<byte[]>(bos.toByteArray(), respHeaders, HttpStatus.CREATED);
}
现在在使用 FileSaver.js 的 javascript 代码中,可以使用以下代码下载文件
var json=angular.toJson("somejsobject");
var url=apiEndPoint+'some url';
var xhr = new XMLHttpRequest();
//headers('X-File-Name')
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 201) {
var res = this.response;
var fileName=this.getResponseHeader('X-File-Name');
var data = new Blob([res]);
saveAs(data, fileName); //this from FileSaver.js
}
}
xhr.open('POST', url);
xhr.setRequestHeader('Authorization','Bearer ' + token);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'arraybuffer';
xhr.send(json);
以上将下载文件
在 Rails 中,我这样做:
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));
}
});
}
诀窍是window.location部分。 控制器的方法如下所示:
# GET /files/{:id}/download_file/
def download_file
send_file(@file.file,
:disposition => 'attachment',
:url_based_filename => false)
end
使用
window.open<\/code>
https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Window\/open<\/a>
例如,您可以将这行代码放在点击处理程序中:
window.open('/file.txt', '_blank');
好的,这是使用 MVC 时的工作代码,您从控制器获取文件
假设你有你的字节数组声明和填充,你唯一需要做的就是使用 File 函数(使用 System.Web.Mvc)
byte[] bytes = .... insert your bytes in the array
return File(bytes, System.Net.Mime.MediaTypeNames.Application.Octet, "nameoffile.exe");
然后,在同一个控制器中,添加这两个功能
protected override void OnResultExecuting(ResultExecutingContext context)
{
CheckAndHandleFileResult(context);
base.OnResultExecuting(context);
}
private const string FILE_DOWNLOAD_COOKIE_NAME = "fileDownload";
/// <summary>
/// If the current response is a FileResult (an MVC base class for files) then write a
/// cookie to inform jquery.fileDownload that a successful file download has occured
/// </summary>
/// <param name="context"></param>
private void CheckAndHandleFileResult(ResultExecutingContext context)
{
if (context.Result is FileResult)
//jquery.fileDownload uses this cookie to determine that a file download has completed successfully
Response.SetCookie(new HttpCookie(FILE_DOWNLOAD_COOKIE_NAME, "true") { Path = "/" });
else
//ensure that the cookie is removed in case someone did a file download without using jquery.fileDownload
if (Request.Cookies[FILE_DOWNLOAD_COOKIE_NAME] != null)
Response.Cookies[FILE_DOWNLOAD_COOKIE_NAME].Expires = DateTime.Now.AddYears(-1);
}
然后你就可以调用你的控制器下载并获得“成功”或“失败”回调
$.fileDownload(mvcUrl('name of the controller'), {
httpMethod: 'POST',
successCallback: function (url) {
//insert success code
},
failCallback: function (html, url) {
//insert fail code
}
});
The HTML Code:-
'<button type="button" id="GetFile">Get File!</button>'
The 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);
}
});
});'
我找到了一个修复,虽然它实际上并没有使用 ajax,但它确实允许您使用 javascript 调用来请求下载,然后在下载实际开始时获得回调。 如果链接运行服务器端脚本,在发送文件之前需要一点时间来编写文件,我发现这很有帮助。 所以你可以提醒他们它正在处理,然后当它最终发送文件时删除该处理通知。 这就是为什么我想尝试通过 ajax 加载文件的原因,这样我就可以在请求文件时发生一个事件,而在它实际开始下载时发生另一个事件。
头版的js
function expdone()
{
document.getElementById('exportdiv').style.display='none';
}
function expgo()
{
document.getElementById('exportdiv').style.display='block';
document.getElementById('exportif').src='test2.php?arguments=data';
}
内嵌框架
<div id="exportdiv" style="display:none;">
<img src="loader.gif"><br><h1>Generating Report</h1>
<iframe id="exportif" src="" style="width: 1px;height: 1px; border:0px;"></iframe>
</div>
然后是另一个文件:
<!DOCTYPE html>
<html>
<head>
<script>
function expdone()
{
window.parent.expdone();
}
</script>
</head>
<body>
<iframe id="exportif" src="<?php echo "http://10.192.37.211/npdtracker/exportthismonth.php?arguments=".$_GET["arguments"]; ?>"></iframe>
<script>document.getElementById('exportif').onload= expdone;</script>
</body></html>
我认为有一种方法可以使用 js 读取获取数据,因此不需要 php。 但我不知道它,我使用的服务器支持 php,所以这对我有用。 以为我会分享它以防它对任何人有帮助。
如果服务器在响应中写回文件(包括 cookie,如果您使用它们来确定文件下载是否开始),只需创建一个包含值的表单并提交它:
function ajaxPostDownload(url, data) {
var $form;
if (($form = $('#download_form')).length === 0) {
$form = $("<form id='download_form'" + " style='display: none; width: 1px; height: 1px; position: absolute; top: -10000px' method='POST' action='" + url + "'></form>");
$form.appendTo("body");
}
//Clear the form fields
$form.html("");
//Create new form fields
Object.keys(data).forEach(function (key) {
$form.append("<input type='hidden' name='" + key + "' value='" + data[key] + "'>");
});
//Submit the form post
$form.submit();
}
用法:
ajaxPostDownload('/fileController/ExportFile', {
DownloadToken: 'newDownloadToken',
Name: $txtName.val(),
Type: $txtType.val()
});
控制器方法:
[HttpPost]
public FileResult ExportFile(string DownloadToken, string Name, string Type)
{
//Set DownloadToken Cookie.
Response.SetCookie(new HttpCookie("downloadToken", DownloadToken)
{
Expires = DateTime.UtcNow.AddDays(1),
Secure = false
});
using (var output = new MemoryStream())
{
//get File
return File(output.ToArray(), "application/vnd.ms-excel", "NewFile.xls");
}
}
如果您想使用 jQuery File Download ,请注意 IE 的这一点。 您需要重置响应,否则将无法下载
//The IE will only work if you reset response
getServletResponse().reset();
//The jquery.fileDownload needs a cookie be set
getServletResponse().setHeader("Set-Cookie", "fileDownload=true; path=/");
//Do the reset of your action create InputStream and return
您的操作可以实现ServletResponseAware
以访问getServletResponse()
可以肯定的是,你不能通过 Ajax 调用来做到这一点。
但是,有一种解决方法。
脚步 :
如果您使用 form.submit() 下载文件,您可以做的是:
如果您想在制作 form.submit() 后决定是否需要下载文件,这将很有帮助,例如:在 form.submit() 上,可能会在服务器端发生异常,而不是崩溃时,您可能需要在客户端显示自定义消息,在这种情况下,此实现可能会有所帮助。
还有另一种解决方案可以在 ajax 中下载网页。 但我指的是必须首先处理然后下载的页面。
首先,您需要将页面处理与结果下载分开。
1) ajax 调用中只进行页面计算。
$.post("CalculusPage.php", { calculusFunction: true, ID: 29, data1: "a", data2: "b" }, function(data, status) { if (status == "success") { /* 2) In the answer the page that uses the previous calculations is downloaded. For example, this can be a page that prints the results of a table calculated in the ajax call. */ window.location.href = DownloadPage.php+"?ID="+29; } } ); // For example: in the CalculusPage.php if ( !empty($_POST["calculusFunction"]) ) { $ID = $_POST["ID"]; $query = "INSERT INTO ExamplePage (data1, data2) VALUES ('".$_POST["data1"]."', '".$_POST["data2"]."') WHERE id = ".$ID; ... } // For example: in the DownloadPage.php $ID = $_GET["ID"]; $sede = "SELECT * FROM ExamplePage WHERE id = ".$ID; ... $filename="Export_Data.xls"; header("Content-Type: application/vnd.ms-excel"); header("Content-Disposition: inline; filename=$filename"); ...
我希望这个解决方案对许多人有用,就像对我一样。
这在任何浏览器中都可以正常工作(我使用的是 asp.net core)
function onDownload() { const api = '@Url.Action("myaction", "mycontroller")'; var form = new FormData(document.getElementById('form1')); fetch(api, { body: form, method: "POST"}) .then(resp => resp.blob()) .then(blob => { const url = window.URL.createObjectURL(blob); $('#linkdownload').attr('download', 'Attachement.zip'); $('#linkdownload').attr("href", url); $('#linkdownload') .fadeIn(3000, function() { }); }) .catch(() => alert('An error occurred')); }
<button type="button" onclick="onDownload()" class="btn btn-primary btn-sm">Click to Process Files</button> <a role="button" href="#" style="display: none" class="btn btn-sm btn-secondary" id="linkdownload">Click to download Attachments</a> <form asp-controller="mycontroller" asp-action="myaction" id="form1"></form>
function onDownload() {
const api = '@Url.Action("myaction", "mycontroller")';
//form1 is your id form, and to get data content of form
var form = new FormData(document.getElementById('form1'));
fetch(api, { body: form, method: "POST"})
.then(resp => resp.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
$('#linkdownload').attr('download', 'Attachments.zip');
$('#linkdownload').attr("href", url);
$('#linkdownload')
.fadeIn(3000,
function() {
});
})
.catch(() => alert('An error occurred'));
}
我尝试了 Ajax 和 HttpRequest 方法来获取我的结果下载文件,但我失败了,最后我使用以下步骤解决了我的问题:
在我的 html 代码中实现了一个简单的隐藏表单:
<form method="post" id="post_form" style="display:none" action="amin.php" >
<input type="hidden" name="action" value="export_xlsx" />
<input type="hidden" name="post_form_data" value="" />
</form>
带有“action”名称的输入用于在我的 php 代码中调用函数,带有“post_form_data”名称的输入用于发送无法使用 GET 发送的表的长数据。 将此数据编码为 json,并将 json 放入输入中:
var list = new Array();
$('#table_name tr').each(function() {
var row = new Array();
$(this).find('td').each(function() {
row.push($(this).text());
});
list.push(row);
});
list = JSON.stringify(list);
$("input[name=post_form_data]").val(list);
现在,表单已经准备好输入我想要的值,只需要触发提交。
document.getElementById('post_form').submit();
并做了! 虽然我的结果是一个文件(对我来说是 xlsx 文件),但页面不会被重定向,并且文件会立即在最后一页开始下载,因此无需使用 iframe 或 window.open 等。
如果您尝试做这样的事情,这应该是一个简单的技巧😉。
API em LARAVEL , onde é criado o arquivo (xlsx) usando \Maatwebsite\Excel\Excel
AJAX , é enviado o Token pra a validação da API e tbm enviado um form que é usado como filtros para o relatório。
$('.btnBuscaRelatorio').on('click', function() {
var form = new FormData(document.getElementById('formRelatorios'));
$.ajax({
url: 'http://' + ip + '/api/caminho_do_relatorio',
method: 'POST',
xhrFields: {
responseType: 'blob'
},
headers: {
Accept: "application/json",
Authorization: "Bearer " + token,
},
processData: false,
mimeType: "multipart/form-data",
contentType: false,
data: form,
})
.done(function(data) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(data);
a.href = url;
a.download = 'nome_do_arquivo.xlsx';
document.body.append(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
})
.fail(function(data){
toastr.error("Erro na busca do relatório, contate o suporte.");
});
});
我在这个问题上挣扎了很长时间。 最后, 这里<\/a>建议的一个优雅的外部库帮助了我。
"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.