与后台同步——实时获取上传/导入进度
</pre><pre name="code" class="javascript">
前几天在做一个功能,是导入csv文件。按照正常的写法写完之后,发现运行的速度很慢,一个原因是写的时候没有多大考虑性能,一个原因就是原本的csv文件就10列,要根据这10列进行扩展,分别插到2个30字段的表和一个10字段的表,所以信息的获取只能依靠查询数据库。针对第一个性能,将一些不必要的查询去掉(经销商一个文件就一个,无需多次查询),能合并的查询就合并(查询始发地和目的地)。速度是快了一些,测试1000条数据,本来需要4分钟,后来少了一半多。原本前端页面在选择文件,点击导入之后是没有响应的。如果让用户白瞎瞎等个几分钟,指不定就会做点什么。。。所以觉得给弄个进度条,用户体验会好点。
看了下自己在html里面的代码,提交csv文件时候,用的是<file>控件加上form.submit方式提交到后台,后台使用一个formObj接受。
第一个方法:使用XMLHttpRequest
(相关参考连接http://blog.csdn.net/qinpeng100423/article/details/8637797
http://blog.csdn.net/liujiahan629629/article/details/17126727)
创建对象--注册回调方法--设置与服务器交互的参数--向服务器发送数据1.创建对象 //创建请求对象
function GetXmlHttpObject()
{
var xmlHttp=null;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
2.注册回调方法
var xhr = new window.XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState > 2){
var tmpText = xhr.responseText.substring(oldSize);
oldSize = xhr.responseText.length;
if(tmpText.length > 0 ){
// 设置文本
t.innerHTML = tmpText + "/6";
// 设置进度条
var width = parseInt(tmpText)/6*300;
bg.style.width = width+"px";
}
}
if(xhr.readyState == 4){
// 请求执行完毕
t.innerHTML = "执行完毕";
bg.style.width = "300px";
}
}
3.设置与服务器交互的参数
xhr.open("get",url);
xhr.setRequestHeader("Content-type","application/x-www-four-urlencoded");
4.向服务器发送数据
var xmlMessage = buildPOST(frm);//看下一条
xhr.send(xmlMessage);
后面发现了一个问题,就是提交的时候没有把表单带上去,就找到了一个方法,将表单的name传到服务器上。
function buildPOST(theFormName) {
var theForm=new Array();
theForm = document.getElementById("frm") ;
var qs = ''
for (e=0;e<theForm.elements.length;e++) {
if (theForm.elements[e].name!='') {
var name = theForm.elements[e].name;
qs+=(qs=='')?'':'&'
qs+= name+'='+escape(theForm.elements[e].value);
}
}
qs+="";
return qs
}
表单能够提交之后又碰到一个新的问题,底层解析不了、、、这块又是公共模块,不好去改。
认真看了下程序,想了另外一个方法。在客户端循环的发送查询请求,如果有数据则改变进度条。
因为A类在页面生成的时候就创建了对象,而B是调用其方法的时候创建,所以就将变量设在A类之中,A类设为B类的成员变量。这样在A存在的话即可以计数。
具体写法是这样的:
html里面
<div align="left">
正在检查第<span id="progressCheckText"></span>条数据<progress value="0" max="100" id="mCheckProgress"></progress>
<br />
正在插入第<span id="progressInsertText"></span>条数据<progress value="0" max="100" id="mInsertProgress"></progress>
</div>
JS里面
//通过Excel导入商品
function ImportAttachment()
{
$("#pageloading").show();
var url = '<%m_webPage & importURL;%>';
var frm = window.document.frm;
frm.action = url;
frm.submit();
window.setInterval(refreshDiv,1000); //定时调用
}
//显示进度条
function refreshDiv(){
var url="AAAAA.dll?page=AAAAAA&pcmd=getMsgid";
var httpRet = AjaxHttpGet(url);
var xmlRet = Xparse(httpRet);
var checkCount = xmlRet.getValueByName("checkCount");
var sumCount = xmlRet.getValueByName("sumCount");
var insertCount = xmlRet.getValueByName("insertCount");
if(sumCount<1)
return false;
var a = parseInt(checkCount)+2;
mCheckProgress.value=a/sumCount*100;
progressCheckText.innerHTML = a+"/"+sumCount;
mInsertProgress.value=insertCount/sumCount*100;
progressInsertText.innerHTML = insertCount+"/"+sumCount;
}
在服务器端
void BBBBBB::getMsgid()
{
m_webPage & "<sumCount>"& cFileImportProc->sumCount &"</sumCount>";
m_webPage & "<checkCount>"& cFileImportProc->checkCount &"</checkCount>";
m_webPage & "<insertCount>"& cFileImportProc->insertCount &"</insertCount>";
return;
}
这样就能显示了