it-swarm-ko.tech

XMLHttpRequest에서 진행하는 방법

XMLHttpRequest (업로드 된 바이트, 다운로드 된 바이트)의 진행률을 얻을 수 있습니까?

사용자가 큰 파일을 업로드 할 때 진행률 표시 줄을 표시하는 데 유용합니다. 표준 API는 그것을 지원하지 않는 것 같지만, 어떤 브라우저에도 비표준 확장이 있습니까? 클라이언트가 업로드/다운로드 한 바이트 수를 알고 있기 때문에 결국에는 매우 분명한 기능인 것 같습니다.

참고 : 나는 "진행을 위해 서버 설문 조사"대안을 알고 있습니다 (지금 내가하고있는 일입니다). 이 문제의 주된 문제점 (복잡한 서버 측 코드 제외)은 일반적으로 큰 파일을 업로드하는 동안 대부분의 ISP가 열악한 업스트림을 제공하기 때문에 사용자 연결이 완전히 제한된다는 것입니다. 따라서 추가 요청을하는 것은 내가 바라는 것처럼 반응하지 않습니다. 브라우저가 항상 가지고있는이 정보를 얻는 방법 (표준이 아닐 수도 있음)이 있기를 바랐습니다.

130
Pete

업로드 된 바이트의 경우 매우 쉽습니다. xhr.upload.onprogress 이벤트 만 모니터링하십시오. 브라우저는 업로드해야하는 파일의 크기와 업로드 된 데이터의 크기를 알고 있으므로 진행 정보를 제공 할 수 있습니다.

다운로드 된 바이트 (xhr.responseText로 정보를 가져올 때)의 경우 브라우저가 서버 요청에서 몇 바이트를 전송할지 알 수 없기 때문에 조금 더 어렵습니다. 이 경우 브라우저가 아는 유일한 것은 수신하는 바이트의 크기입니다.

이에 대한 해결책이 있습니다. 브라우저가 수신 할 바이트의 총 크기를 얻으려면 서버 스크립트에 Content-Length 헤더를 설정하는 것으로 충분합니다.

자세한 내용은 https://developer.mozilla.org/en/Using_XMLHttpRequest 로 이동하십시오.

예 : 서버 스크립트가 Zip 파일을 읽습니다 (5 초 소요).

$filesize=filesize('test.Zip');

header("Content-Length: " . $filesize); // set header length
// if the headers is not set then the evt.loaded will be 0
readfile('test.Zip');
exit 0;

이제 총 길이를 알고 있기 때문에 서버 스크립트의 다운로드 프로세스를 모니터링 할 수 있습니다.

function updateProgress(evt) 
{
   if (evt.lengthComputable) 
   {  // evt.loaded the bytes the browser received
      // evt.total the total bytes set by the header
      // jQuery UI progress bar to show the progress on screen
     var percentComplete = (evt.loaded / evt.total) * 100;  
     $('#progressbar').progressbar( "option", "value", percentComplete );
   } 
}   
function sendreq(evt) 
{  
    var req = new XMLHttpRequest(); 
    $('#progressbar').progressbar();    
    req.onprogress = updateProgress;
    req.open('GET', 'test.php', true);  
    req.onreadystatechange = function (aEvt) {  
        if (req.readyState == 4) 
        {  
             //run any callback here
        }  
    };  
    req.send(); 
}
134
albanx

Firefox는 XHR 다운로드 진행 이벤트 를 지원합니다.

9
Markus Peröbner

AJAX 패턴에 대한 진행 표시기에 대한 좋은 설명이 있습니다.

http://ajaxpatterns.org/Progress_Indicator

가장 유망한 접근법 중 하나는 서버로 다시 두 번째 통신 채널을 열어서 얼마나 많은 전송이 완료되었는지 묻는 것 같습니다.

8
Sean McMains
7
Maciej Łebkowski

전체 업로드의 경우 처리 방법이없는 것 같지만 다운로드하려는 것과 비슷한 것이 있습니다. readyState가 3이면, responseText를 주기적으로 쿼리하여 String으로 다운로드 한 모든 컨텐츠를 얻을 수 있습니다 (IE에서는 작동하지 않음). 주어진 시간에 다운로드 된 바이트는 responseText에 저장된 문자열의 총 바이트와 같습니다.

업로드 질문에 대한 전체 또는 전혀 접근 방식의 경우, 업로드를 위해 문자열을 전달해야하기 때문에 readyState 0 및 1에 전송 된 총 바이트는 0이되고 readyState에 대한 총계는 2는 전달한 문자열의 총 바이트입니다. readyState 3 및 4에서 보내고받은 총 바이트는 원래 문자열의 바이트와 responseText의 총 바이트를 합한 것입니다.

5
Orclev
<!DOCTYPE html>
<html>
<body>
<p id="demo">result</p>
<button type="button" onclick="get_post_ajax();">Change Content</button>
<script type="text/javascript">
        function update_progress(e)
        {
          if (e.lengthComputable)
          {
            var percentage = Math.round((e.loaded/e.total)*100);
            console.log("percent " + percentage + '%' );
          }
          else 
          {
                console.log("Unable to compute progress information since the total size is unknown");
          }
        }
        function transfer_complete(e){console.log("The transfer is complete.");}
        function transfer_failed(e){console.log("An error occurred while transferring the file.");}
        function transfer_canceled(e){console.log("The transfer has been canceled by the user.");}
        function get_post_ajax()
        {
                var xhttp;
                if (window.XMLHttpRequest){xhttp = new XMLHttpRequest();}//code for modern browsers} 
                else{xhttp = new ActiveXObject("Microsoft.XMLHTTP");}// code for IE6, IE5               
                xhttp.onprogress = update_progress;
                xhttp.addEventListener("load", transfer_complete, false);
                xhttp.addEventListener("error", transfer_failed, false);
                xhttp.addEventListener("abort", transfer_canceled, false);              
                xhttp.onreadystatechange = function()
                {
                if (xhttp.readyState == 4 && xhttp.status == 200)
                {
                        document.getElementById("demo").innerHTML = xhttp.responseText;
                }
                };
          xhttp.open("GET", "http://it-tu.com/ajax_test.php", true);
          xhttp.send();
        }
</script>
</body>
</html>

Result

3
Forums Lover

Apache 설치에 액세스하고 타사 코드를 신뢰하는 경우 Apache upload progress module (Apache를 사용하는 경우 nginx upload progress module)도 있습니다 ).

그렇지 않으면 파일 상태를 요청하기 위해 대역 외에서 벗어날 수있는 스크립트를 작성해야합니다 (예를 들어 tmp 파일의 파일 크기 확인).

파이어 폭스 3에서 진행중인 작업이 있습니다. 브라우저에 업로드 진행 지원을 추가한다고 생각하지만 모든 브라우저에 들어가서 한동안 널리 채택되지는 않습니다 (더 이상 불쌍합니다).

2
Aeon