Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript XMLHttpRequest级别2-确定上载是否完成_Javascript_Ajax_Upload_Xmlhttprequest - Fatal编程技术网

Javascript XMLHttpRequest级别2-确定上载是否完成

Javascript XMLHttpRequest级别2-确定上载是否完成,javascript,ajax,upload,xmlhttprequest,Javascript,Ajax,Upload,Xmlhttprequest,我使用ajax上传文件。 上传文件后,php应该检查它(mime、大小、病毒(clamscan)等等)——对于较大的文件,这需要几秒钟的时间。当文件上传时,一个HTML5正在填充,当文件准备好并且PHP开始检查时,进度应该切换到不确定。我想到了这样做的方法(这两种方法都不起作用): 检查upload.onload事件 xhr.upload.addEventListener("load", function (e) { $("#uploadprogress").attr("value",

我使用ajax上传文件。 上传文件后,php应该检查它(mime、大小、病毒(clamscan)等等)——对于较大的文件,这需要几秒钟的时间。当文件上传时,一个HTML5
正在填充,当文件准备好并且PHP开始检查时,进度应该切换到不确定。我想到了这样做的方法(这两种方法都不起作用):

检查upload.onload事件

xhr.upload.addEventListener("load", function (e) {
    $("#uploadprogress").attr("value", false);
    $("#uploadprogress").attr("max", false);
    $("#progress").text("Checking file...");
});
这不起作用,因为
onload
-事件在请求准备就绪时触发,而不是在上载准备就绪时触发

检查上传进度百分比是否为100%

xhr.upload.addEventListener("progress", function (e) {
    if (e.lengthComputable && e) {
        p = (e.loaded / e.total);
        if (p==1) {
            $("#uploadprogress").attr("value", false);
            $("#uploadprogress").attr("max", false);
            $("#progress").text("Checking file...");
        } else {
            var percent = Math.ceil(p * 1000) / 10;
            $("#uploadprogress").val(e.loaded);
            $("#uploadprogress").attr("max", e.total);
            $("#progress").text("Uploading... " + percent + "%");
        }
   }
}
});
这是行不通的,因为上传百分比有时会在97%左右停止,尽管上传已经完成,PHP开始处理文件


是否还有其他可能检查此问题?

这是hTML5规范的一个相对已知的缺陷,当他们可以轻松地扩展它以添加诸如剩余时间和传输速度等信息时

您是否考虑过使用
math.round
而不是
math.ceil
来计算
var percent
,这样您就有点模糊了,这将有助于降低大约几个百分点


如果用户界面卡在上,您还应该为loadComplete添加另一个侦听器。您要侦听的事件是XHR对象(而不是XHR.upload)上的
readystatechange
<上传完成发送后,code>readyState为
4
服务器关闭连接
loadend
/
load
在上载完成时激发,无论服务器是否关闭连接。仅供参考,以下是您可以收听的事件以及它们何时触发:

    var xhr = new XMLHttpRequest();

    // ...
    // do stuff with xhr
    // ...

    xhr.upload.addEventListener('loadstart', function(e) {
      // When the request starts.
    });
    xhr.upload.addEventListener('progress', function(e) {
      // While sending and loading data.
    });
    xhr.upload.addEventListener('load', function(e) {
      // When the request has *successfully* completed.
      // Even if the server hasn't responded that it finished.
    });
    xhr.upload.addEventListener('loadend', function(e) {
      // When the request has completed (either in success or failure).
      // Just like 'load', even if the server hasn't 
      // responded that it finished processing the request.
    });
    xhr.upload.addEventListener('error', function(e) {
      // When the request has failed.
    });
    xhr.upload.addEventListener('abort', function(e) {
      // When the request has been aborted. 
      // For instance, by invoking the abort() method.
    });
    xhr.upload.addEventListener('timeout', function(e) {
      // When the author specified timeout has passed 
      // before the request could complete.
    });

    // notice that the event handler is on xhr and not xhr.upload
    xhr.addEventListener('readystatechange', function(e) {
      if( this.readyState === 4 ) {
        // the transfer has completed and the server closed the connection.
      }
    });

检查readyState,
如果(readyState==4){//它已完成,请将代码放在此处}

基于

让我们来看一个完整的工作示例

// YOUR (SIMPLE) JAVASCRIPT FILE
var form = new FormData(), xhr = new XMLHttpRequest();
form.append('inputname', YOURFILE);

xhr.open('POST', 'http://oneserver/onephpfile', true);
xhr.setRequestHeader('X-CSRF-Token', 'somestring');
xhr.onreadystatechange = function () {
    if ((xhr.readyState === 4) && (xhr.status === 200))
        // do other thing with xhr.responseText.trim()
};

xhr.upload.addEventListener('loadstart', showProgressBarFunction, false);
xhr.upload.addEventListener('progress',  updateProgressBarFunction, false);
xhr.upload.addEventListener('load',      updateProgressBarFunction, false);
xhr.send(form);

// YOUR FIRST (SIMPLE) PHP FILE
header('Content-Type: text/plain; charset=utf-8');
header('Cache-Control: no-cache, must-revalidate');

sleep(20);
echo 'file processing ended';
使用第一个PHP文件,您将看到:10%。。。50%... 75%... '用Firefox(4/10/28/32)和IE(10/11)做其他事情然而我们将看到:10%。。。50%... 75%... 100%... '用Chrome/Chrome(33/37)和Opera(24)做其他事情

//您的第二个(简单)PHP文件
标题('Content-Encoding:chunked',true);
标题('Content-Type:text/plain;charset=utf-8');
标头('Cache-Control:无缓存,必须重新验证');
ini_集合(“输出缓冲”,false);
ini_集(“隐式_刷新”,真);
ob_隐式_刷新(真);
对于($i=0;$i

使用第二个PHP文件,您将看到:10%。。。50%... 75%... 100%... '用Chrome/Chrome(33/37/53)、Opera(24/42)、Firefox(4/10/28/32/45)、IE(10/11)和Edge(14)做其他事情

但我不想检查连接是否关闭,因为上传完成后,PHP会检查文件,这需要大约10秒的时间,并返回一些JSON。当PHP开始检查文件时(=上传完成时),当文件传输完成时,进度条应切换到
未终止
,当脚本检查完文件时,
loadend
/
load
事件触发(当PHP关闭连接时)
readystatechange
事件以
readyState==4
触发。因此,出于您的目的,请在
readystatechange
事件中将进度条切换到
indereminated
。看:不起作用。这是我的JS:假设PHP脚本只是
sleep(10)。现在我想显示这10秒的
未终止的
进度条您可能有浏览器问题。我刚刚在Chrome 25.0.1364.172和27.0.1449.0上测试了它(使用了一些语法修复等),它工作正常。但是,FF 19.0.2正在同时启动
load
/
loadend
/
readyState 4
。请确保将侦听器添加到upload属性,而不是直接添加到xhr。
// YOUR SECOND (SIMPLE) PHP FILE
header('Content-Encoding: chunked', true);
header('Content-Type: text/plain; charset=utf-8');
header('Cache-Control: no-cache, must-revalidate');
ini_set('output_buffering', false);
ini_set('implicit_flush', true);
ob_implicit_flush(true);
for ($i = 0; $i < ob_get_level(); $i++)
    ob_end_clean();
echo ' ';

sleep(20);
echo 'file processing ended';