好的,所以我认为没有办法做到这一点,没有使用iframe,或通过ajax调用提交我的表单,但无论如何,我想我会问。< / p>
假设我有一个带有以下配置的Web服务器
public/
├── file.php
├── index.php
└── myfile.csv
在index.php
我有一张表格。它是 POST 表单,其行为为file.php
。附加到该表单的是一个JS事件处理程序,用于在提交时将一些“ Loading ... ”文本插入到DOM中。
<!doctype html>
<html>
<body>
<h1>Reports</h1>
<form action="file.php" id="my-form" method="post">
<input type="submit" value="Generate and Download File" id="submit-button">
</form>
<div id="result"></div>
<script>
function addEventListener(el, eventName, handler) {
if (el.addEventListener) {
el.addEventListener(eventName, handler);
} else {
el.attachEvent('on' + eventName, function(){
handler.call(el);
});
}
}
var form = document.getElementById('my-form');
// On form submit, display a Loading... message
addEventListener(form, 'submit', function() {
document.getElementById('result').innerHTML = '<h3>Loading...</h3>';
});
</script>
</body>
</html>
非常简单。现在,file.php
,想象一下这是在做一些繁重的计算,当它完成后,它会生成一个.CSV文件并提供下载。
以下示例模拟了我的脚本正在执行的操作:
<?php
// Dummy file
$file = 'myfile.csv';
// Simulate heavy calculations...
sleep(3);
if (file_exists($file)) {
// Download the file
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
为了完整性,这里是myfile.csv
:
Hello,World
现在,我的问题是:
我的文件提供后,下载开始,我可以删除插入DOM的“正在加载...”文本吗?
在同步表单获得POST后,是否有可以触发的JS事件?
就像我说的那样,我认为没有,但我想查一下。
答案 0 :(得分:-1)
您在这里所做的似乎是使用浏览器“缓存”继续显示页面,即使浏览器已请求返回文件的其他页面而不是要解释的HTML。
在我的经验中,我们使用jquery Ajax来显示/隐藏“加载”DIV。
(向下滚动查看非ajax解决方案)
$.ajax({
url: script_url,
cache: false,
async: sync_type,
type: "POST",
data: form_data,
dataType: "html",
beforeSend: function(jqXHR, settings)
{
//BUILD LOADING HTML
loading_html = '<div class="ajax-loading"> </div>';
//SHOW LOADING
switch(return_mode)
{
case 'append':
$('#'+container_id).addClass('ajax-loading');
break;
case 'prepend':
$('#'+container_id).addClass('ajax-loading');
break;
default:
$('#'+container_id).html(loading_html);
break;
}//END SWITCH RETURN MODE
},//END FUNCTION BEFORESEND
success: function(html_returned, success_code, jqXHR_object)
{
switch(return_mode)
{
case 'append':
//APPEND HTML RESPONSE
$('#'+container_id).append(html_returned);
break;
case 'prepend':
$('#'+container_id).prepend(html_returned);
break;
default:
//REPLACE CONTAINER CONTENTS WITH HTML RESPONSE
$('#'+container_id).html(html_returned);
break;
}//END SWITCH RETURN MODE
},//END FUNCTION SUCCESS
error: function(jqXHR, exception)
{
//SHOW ERRORS
if (jqXHR.status === 0)
{
//alert('Not connect.\n Verify Network.');
} else if (jqXHR.status == 404)
{
//alert('Requested page not found. [404]');
} else if (jqXHR.status == 500)
{
//alert('Internal Server Error [500].');
} else if (exception === 'parsererror')
{
//alert('Requested JSON parse failed.');
} else if (exception === 'timeout')
{
//alert('Time out error.');
} else if (exception === 'abort')
{
//alert('Ajax request aborted.');
} else {
//alert('Uncaught Error.\n' + jqXHR.responseText);
}//END IF JQXHR.STATUS === 0
},//END FUNCTION ERROR
complete: function(jqXHR, textStatus)
{
//REMOVE LOADING CLASS
$('#'+container_id).removeClass('ajax-loading');
}
});
所有这一切,如果你真的不能使用jquery ajax调用,那么你可能会尝试用一些CSS来欺骗页面。例如,有<div id="loading_div" class="loading" style="display: none"></div>
显示您的加载详细信息(微调器等)
当他们点击提交表单然后显示加载DIV。
getElementById('loading_div').css("display", "block");
然后在页面底部,有一个javascript部分说明:
<script>
//HIDE THE LOADING DIV
getElementById('loading_div').css("display", "none");
</script>
如果您的file.php脚本将浏览器重定向回您的页面:
header("Location: my_page_url.php");
然后他们会看到这个加载div直到文件被处理掉,然后是重新加载的页面(但下载对话框将保留)