文件上传进度条

3

如果您使用以下技术之一开发文件上传进度条:

Ajax Javascript HTML 基于C的CGI

您可能会遇到一个问题。 我无法从CGI脚本中读取每个更新的进度条值。

/*****************CLIENT SIDE CODE*************************/

var intervalID;
var percentage;
var request;
var tempvar=0;
var progress;


function polling_start() {   // This is called when user hits FILEULOAD button
        //alert ("polling_start");
        intervalID = window.setInterval(send_request,1000);
}

window.onload = function (){
        request  = initXMLHttpClient();
        progress = document.getElementById('progress');
}

function initXMLHttpClient() {
        //alert("send_request");
        if (window.XMLHttpRequest){
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
        }
        else{
        // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
return xmlhttp
}

function send_request()
{
request.onreadystatechange = request_handler;
request.open("GET","progress_bar.txt",true);
request.send(null);
}

function request_handler()
{
        if (request.readyState == 4 && request.status == 200)
        {
        document.getElementById("progress").innerHTML= request.responseText + '%';
        document.getElementById("progress").style.width = request.responseText + '%';
        document.getElementById("progress").style.backgroundColor = "green";
        }
}

/***********************SERVER SIDE CODE*****************************/

    cgiFormFileSize("UPDATEFILE", &size);   //UPDATEFILE = file being uploaded
    cgiFormFileName("UPDATEFILE", file_name, 1024);
    cgiFormFileContentType("UPDATEFILE", mime_type, 1024);
    buffer = malloc(sizeof(char) * size);

        if (cgiFormFileOpen("UPDATEFILE", &file) != cgiFormSuccess) {
        exit(1);
    }
    output = fopen("/tmp/cgi.tar.gz", "w+");

    printf("The size of file is: %d bytes", size);
    inc = size/(1024*100);

        while (cgiFormFileRead(file, b, sizeof(b), &got_count) == cgiFormSuccess)
        {
        fwrite(b,sizeof(char),got_count,output);
        i++;
                if(i == inc && j<=100)
                {
                fptr = fopen("progress_bar.txt", "w");
                fprintf(fptr, "%d" ,j);
                fseek(fptr, 0, SEEK_SET);
                i = 0;
                fflush(fptr);
                fclose(fptr);
                j++;   // j is the progress bar increment value
                }
        }

    fclose(output);
    cgiFormFileClose(file);
    retval = system("mkdir /tmp/update-tmp;\
                     cd /tmp/update-tmp;\
                     tar -xzf ../cgi.tar.gz;\
                     bash -c /tmp/update-tmp/update.sh");
}


/********************************************************************/

因此,Ajax无法读取“j”的每个递增值。因此,进度条会在CGI停止写入文本文件后立即启动。但是,Ajax能够显示从1到100的值(如果我放置sleep(1);则可以看到进度条每秒递增一次),但时间不合适。


1
这不是一个问题。请提供更多的信息和代码。 - mVChr
你卡在哪个环节了? - Marcel Korpel
虽然这并不能解决你的问题,但你应该使用 var xmlhttp; 在本地声明 xmlhttp - Marcel Korpel
我猜这可能是一个打字错误或其他问题,但在服务器端你正在写入'progress_bar.xml',而在客户端你试图读取'progress_bar.txt'。 - Marcel Korpel
哦,对此我很抱歉......但在我的代码中没有这个打字错误。 - Punit
2个回答

0

看一下AJAX进度条,了解如何在JavaScript中实现。您只需要自己编写C代码(提供包含进度百分比的XML的部分;当然,您也可以使用JSON发送此数据)。

更新:如果将间隔增加到例如10000会发生什么?目前,每秒钟通过调用send_request中的request.open重置XMLHTTPRequest连接。


@Punit:文本文件的内容没有更新吗?还是JS部分没有重新读取?在后一种情况下,可能是缓存问题。您是否发送了一个带有过去日期设置的Last-Modified头?请参见HTTP缓存 - Marcel Korpel
@Punit:当你把 console.log(request.readyState + ", " + request.status); 放在 request_handler 中(在 if 外面)时,你看到了什么? - Marcel Korpel
如果我将间隔增加到例如10000,那么同样的事情也会发生。因为1000毫秒=1秒。如果我增加值,轮询延迟和Ajax读取文本文件的延迟也会增加。 - Punit
@Punit:在这种情况下使用警报可能会破坏结果。最好使用控制台输出数据。但是,由于您怀疑这是服务器上的问题,并且我无法访问它(也无法访问测试页面),所以我认为我被卡住了... - Marcel Korpel
@Punit:这不应该成为问题。你可以使用XMLHTTPRequests读取任何文本文件。 - Marcel Korpel
显示剩余9条评论

-2

我不相信仅使用客户端的html/javascript实现进度条是可能的,你需要flash来完成这个任务。

YUI Uploader可以帮助你实现这个功能。


我系统内存非常有限,因此除了上述技术,我无法使用其他任何东西。我正在服务器端使用Ajax从CGI脚本读取数据。 然而,它并不是我想要的方式。if (request.readyState == 4 && request.status == 200) { document.getElementById("progress").innerHTML= request.responseText + '%'; document.getElementById("progress").style.width = request.responseText + '%'; document.getElementById("progress").style.backgroundColor = "green"; }它从在CGI脚本更新的文本文件中读取。 - Punit
因此,它读取文本文件,但无法每次读取更新的值,而是仅读取一次文本文件,CGI已停止写入它,这就是为什么它不进入request.readyState == 4的原因。 - Punit
@Punit:请在你的问题中更新这些信息,这不应该作为评论(回答)的一部分。我认为你还需要展示服务器端的代码。 - Marcel Korpel
3
只使用客户端的HTML/JS是可以实现的。你只需要在服务器端维护一个会话即可。 - BalusC
我的客户端处理工作正常,但我的服务器端不允许Ajax每次读取更新的值。 - Punit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接