我尝试使用
setTimeout
和 top.location.href
在 JSP 页面中顺序下载多个文件,但下载过程未按预期运行。它似乎只处理第一个文件并跳过其他文件,而不是在单独的轮次中执行每个下载(有 2 秒的延迟)。
这是我的代码的简化版本:
<%@page language="java"%>
<%@ page import="java.util.*, java.text.*, java.sql.*"%>
<%@ page import="java.io.*"%>
<%@ page import="sapphire.accessor.QueryProcessor, sapphire.util.DataSet, sapphire.util.StringUtil, sapphire.util.ActionBlock, sapphire.accessor.ActionProcessor, sapphire.util.DBAccess, sapphire.accessor.ActionException"%>
<%@ taglib uri="/WEB-INF/tlds/sapphire.tld" prefix="sapphire" %>
<%@ taglib uri="/WEB-INF/tlds/c.tld" prefix="c" %>
<sapphire:controlledpage allowanonymous="true"/>
<sapphire:page layout="${layout.objectname}">
<sapphire:pagecontent name="content">
<%!
public void writeLog(String logstr) {
String pathFile = "D:\\GenControlChartLog.txt";
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(pathFile, true)));
out.println(new java.util.Date() + " - " + logstr);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
%>
<%
writeLog("Start processing control charts");
String data = requestinfo.getProperty("data");
String sdate = requestinfo.getProperty("sdate");
String edate = requestinfo.getProperty("edate");
String scno = requestinfo.getProperty("scno");
String[] _data = data.split("%3B");
String filenameall = "";
for(int i = 0;i<_data.length;i++) {
String[] __data = _data[i].split(";");
String filename = "ControlChart-"+__data[0]+"-"+i+"-" + new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss").format(new java.util.Date()) +".xlsx";
String success = "";
writeLog("filename = "+ filename);
HashMap hm = new HashMap();
hm.put("filename", filename);
hm.put("keyid1", _data[i]);
hm.put("sdate", sdate);
hm.put("edate", edate);
hm.put("scno", scno);
ActionProcessor ap = new ActionProcessor(application.getInitParameter("nameserverlist"), pageinfo.getConnectionId());
try {
ap.processAction("ControlChartXLXS", "1", hm);
success = "SUCCESS";
writeLog("ControlChartXLXS SUCCESS ");
} catch (ActionException ae) {
success = "FAILURE";
writeLog("error1 :"+ae.getMessage());
} catch (Exception e) {
success = "FAILURE";
writeLog("error2 :"+e.getMessage());
}
if(i>0) {
filenameall +="%3B";
}
filenameall +=filename;
}
%>
<script>
function downloadFile_V2(file, i) {
setTimeout(function() {
top.sapphire.alert( 'into setTimeout Download round ' + i, true );
console.log('into setTimeout Download round ' + i);
top.location.href = "WEB-CUSTOM/Download/DownloadFile_00.jsp?filepath=WEB-CUSTOM/ControlChart/Output/" + file;
}, i * 2000);
}
var _filename = "<%=filenameall%>";
console.log('filearrOG = ' + _filename);
if (_filename != "") {
var filearr = _filename.split("%3B");
console.log('filearr after split = ' + filearr);
top.sapphire.alert('filearr length = ' + filearr.length, true);
for (let i = 0; i < filearr.length; i++) {
top.sapphire.alert('filearr = ' + filearr[i], true);
console.log('filearr = ' + filearr[i]);
downloadFile_V2(filearr[i], i);
}
} else {
top.sapphire.alert('Not Found Document Template!', true);
}
</script>
</sapphire:pagecontent>
</sapphire:page>
问题:
downloadFile_V2 函数应该按顺序触发下载,每轮之间有 2 秒的延迟。但是,仅发生第一次下载,其他下载将被跳过或不触发。
我希望日志显示 进入 setTimeout 下载第 0 轮 进入 setTimeout 下载第 1 轮 进入 setTimeout 下载第 2 轮
但是,它只记录第一轮(进入 setTimeout 下载第 0 轮)。 我尝试过的:
每次下载使用 setTimeout,延迟 i * 2000。 检查了 filearr 数组的长度,看起来是正确的。 检查了是否有任何 JavaScript 错误,但没有显示任何错误。 关于为什么会发生这种情况或者如何解决这个问题有什么建议吗?
出现您面临的问题是因为当您使用
top.location.href
时,它会触发页面导航,从而中断后续 JavaScript 代码的执行。这会导致页面重新加载时仅下载第一个文件,而其他下载请求没有机会执行。
您可以通过动态创建隐藏锚点 (
top.location.href
) 元素来触发下载,而不是使用 <a>
。这允许您按顺序下载文件,而不会导致页面导航。
以下是更新
downloadFile_V2
功能的方法:
function downloadFile_V2(file, i) {
setTimeout(function() {
console.log('into setTimeout Download round ' + i);
// Create a hidden <a> element to trigger the download
var link = document.createElement('a');
link.href = "WEB-CUSTOM/Download/DownloadFile_00.jsp?filepath=WEB-CUSTOM/ControlChart/Output/" + file;
link.download = file; // Set the download attribute to the filename
// Append the link to the body, click it to trigger the download, and then remove it
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}, i * 2000); // Set a 2-second delay between each download
}
var _filename = "<%=filenameall%>";
if (_filename != "") {
var filearr = _filename.split("%3B");
for (let i = 0; i < filearr.length; i++) {
downloadFile_V2(filearr[i], i);
}
} else {
console.log('No files found.');
}