programing

XMLHttpRequest Level 2 - 업로드가 완료되었는지 여부 확인

css3 2023. 9. 12. 20:11

XMLHttpRequest Level 2 - 업로드가 완료되었는지 여부 확인

저는 파일 업로드를 위해 ajax를 사용하고 있습니다.파일이 업로드된 후 php가 확인해야 합니다(마임, 크기, 바이러스(클램스캔) 등). 파일 크기가 큰 경우에는 몇 초 정도 걸립니다.파일이 업로드 되는 동안 HTML5<progress>파일이 준비되고 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 + "%");
        }
   }
}
});

업로드가 완료되고 PHP가 파일을 처리하기 시작했음에도 불구하고 업로드 비율이 약 97%에서 멈추는 경우가 있기 때문에 작동하지 않습니다.

이것을 확인할 다른 가능성이 있습니까?

당신이 듣고 싶은 이벤트는readystatechangeXHR 개체(XHR.Upload가 아닌)에서.readyState4 업로드가 전송을 완료하고 서버가 연결을 닫을 때.loadend/load서버가 연결을 닫는지 여부에 관계없이 업로드가 완료되면 fire.참고로, 여러분이 들을 수 있는 이벤트와 그들이 발포할 때는 다음과 같습니다.

    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.
      }
    });

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)로 '기타 작업 수행!

이는 상대적으로 알려진 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
}

를 합니다 합니다 을 확인합니다.if(readyState==4) {//it has finished, put code here}

언급URL : https://stackoverflow.com/questions/15418608/xmlhttprequest-level-2-determinate-if-upload-finished