2013-03-14 4 views
18

Я использую ajax для загрузки файлов. После того, как файл загружен, php должен проверить его (mime, размер, вирус (clamscan) и т. Д.) - для больших файлов требуется несколько секунд. Пока файл загружается, HTML5 <progress> заполняется, когда файл готов, и PHP начинает проверку, прогресс должен переключиться на неопределенный. Я додумался способов сделать это (что и делают не работы):XMLHttpRequest Уровень 2 - Определить, если загрузка завершена

Проверка событие upload.onload

xhr.upload.addEventListener("load", function (e) { 
    $("#uploadprogress").attr("value", false); 
    $("#uploadprogress").attr("max", false); 
    $("#progress").text("Checking file..."); 
}); 

Это не работает, потому что onload -Event firest когда запрос готов, а не когда загрузка готова.

Проверка процесса загрузки в процентах = 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 начинает обрабатывать файлы

Есть ли еще возможность проверить это?

ответ

47

событие вы хотите слушать это readystatechange на объект XHR (не на XHR.upload). 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. 
     } 
    }); 
+1

Но я не хочу проверять, закрыто ли соединение, потому что после завершения загрузки PHP проверяет файл, который занимает ок. 10 секунд и возвращается с некоторыми JSON. Когда PHP начинает проверять файл (= когда загрузка завершена), индикатор выполнения должен переключиться на 'неопределенный' – ninov

+0

, когда файл завершит передачу, начнется событие' loadend'/'load', когда ваш скрипт завершит проверку файла (который когда PHP закрывает соединение) событие 'readystatechange' запускается с' readyState === 4'. поэтому для ваших целей переключите индикатор выполнения на 'indetermined' на событие' readystatechange'. см .: https://gist.github.com/anonymous/5208652 – zertosh

+0

Не работает. Это мой JS: https://gist.github.com/anonymous/2a2fef447399a3b8e734 Представьте, что скрипт PHP - это просто 'sleep (10);'. Теперь я хочу показать индикатор состояния «неопределенный» за эти 10 секунд – ninov

1

Это относительно известное падение спецификации hTML5, когда они могли легко расширить его, чтобы добавить информацию, такую ​​как timeRemaining и transferSpeed.

Вы считаете, что используете math.round вместо math.ceil для var percent, чтобы вы выпекали немного нечеткости, что помогло бы обойти несколько процентов очков?

Вы также должны добавить еще один слушатель для loadComplete, если вы получаете UI застрял на < 100%, даже если она будет завершена на внутреннем интерфейсе:

//only fires once 
xhr.addEventListener('loadend', uploadComplete, false); 
function uploadComplete(event) { 
    console.log('rejoice...for I have completed'); 
    //do stuff 
} 
0

Проверьте readyState, if(readyState==4) {//it has finished, put code here}

2

Основываясь на https://bugzilla.mozilla.org/show_bug.cgi?id=637002.

Давайте идти на полный рабочий пример ...

// 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/Chromium (33/37) и Opera (24).

// 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'; 

С этой второй PHP файл, вы увидите: 10% ... 50% ... 75% ... 100% ... 'делать другие вещи' с Chrome/Chromium (33/37/53), Opera (24/42), Firefox (4/10/28/32/45), IE (10/11) и Edge (14)!

Смежные вопросы