dse*_*rav 8 javascript php zend-framework
我正在编写一些PHP,它会进行大量处理,然后生成结果报告.以前它会做一个定期的flush(),但我们正在转向Zend Framework,不能再这样做了.相反,我希望在生成报告时有一些更新的状态显示.所以我创建了一个在iframe中加载的进度条,为进度条更新操作和报告生成操作添加了共享内存,并导致输出通过xmlhttprequest加载.一切正常.我的问题是浏览器想要串行而不是并行地执行这两个请求,因此它将请求进度条然后BLOCK直到进度条完成之前它请求实际输出.这意味着该过程永远不会结束,因为真正的工作永远不会开始.
我整个上午都在搜索这个问题并空手而归.有没有办法导致两个连接,或者我只是搞砸了?
我的下一个操作是将处理分开一些,并使状态更新操作执行实际工作,保存结果,然后使用其他操作转储它.这将是非常痛苦的,我想避免它.
function startProgress()
{
var iFrame = document.createElement('iframe');
document.getElementsByTagName('body')[0].appendChild(iFrame);
iFrame.id = 'progressframe';
iFrame.src = '/report/progress';
}
function Zend_ProgressBar_Update(data)
{
document.getElementById('pg-percent').style.width = data.percent + '%';
document.getElementById('pg-text-1').innerHTML = data.text;
document.getElementById('pg-text-2').innerHTML = data.text;
}
function Zend_ProgressBar_Finish()
{
document.getElementById('pg-percent').style.width = '100%';
document.getElementById('pg-text-1').innerHTML = 'Report Completed';
document.getElementById('pg-text-2').innerHTML = 'Report Completed';
document.getElementById('progressbar').style.display = 'none'; // Hide it
}
function ajaxTimeout(){
xmlhttp.abort();
alert('Request timed out');
}
var xmlhttp;
var xmlhttpTimeout;
function loadResults(){
if (window.XMLHttpRequest){
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}else{
// code for IE6, IE5
xmlhttp=new ActiveXObject(\"Microsoft.XMLHTTP\");
}
xmlhttp.open(\"POST\",\"/report/output\",true);
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
clearTimeout(xmlhttpTimeout);
document.getElementById('report-output').innerHTML=xmlhttp.responseText;
}
}
var xmlhttpTimeout=setTimeout(ajaxTimeout,600000); // Ten minutes
xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xmlhttp.send('".file_get_contents("php://input")."');
}
Run Code Online (Sandbox Code Playgroud)
这从以下onload脚本调用:
onload="startProgress(); setTimeout(loadResults,1000);"
Run Code Online (Sandbox Code Playgroud)
问题不在于Javascript.如果您在其中放置alert(),则会在正确的时间触发警报,但浏览器会延迟第二个http事务,直到第一个完成.
谢谢大家的意见.
在我们的开发计划允许的时间范围内,我没有得到满意的答案.似乎每个常见浏览器都希望在与该站点进行多个事务时重用现有的站点连接.我没有想到的任何东西会导致浏览器按需启动并行连接.每当有来自同一服务器的两个请求时,客户端希望以串行方式执行它们.
我最终将处理分成几部分并将其移动到状态栏更新操作中,将报告输出保存到服务器上的临时文件中,然后使状态栏结束功能启动xmlhttprequest以加载结果.输出操作只是吐出临时文件的内容然后将其删除.
使用两个异步 ajax 就可以解决这个问题。对于第一个 ajax 请求,您应该通过调用 php-cli 来启动进程,以在后台深处执行实际工作(这样它就不会过期或取消)并返回进程(任务)的 id。现在,当您获得进程ID后,您可以启动定期ajax来显示所创建的进程。
制作一个包含 process_id、state、user 的数据库表并不是一件坏事。在这种情况下,即使用户在进程运行时关闭浏览器,该进程也会继续直到完成。用户可以重新访问该页面并查看完成的百分比,因为在 cli 中运行的进程会将进度保存到数据库表中。