XMLHttpRequest에서 진행하는 방법
XMLHttpRequest (업로드 된 바이트, 다운로드 된 바이트)의 진행률을 얻을 수 있습니까?
사용자가 큰 파일을 업로드 할 때 진행률 표시 줄을 표시하는 데 유용합니다. 표준 API는 그것을 지원하지 않는 것 같지만, 어떤 브라우저에도 비표준 확장이 있습니까? 클라이언트가 얼마나 많은 바이트가 업로드 / 다운로드되었는지 알고 있기 때문에 결국에는 매우 명백한 기능처럼 보입니다.
참고 : 나는 "진행을 위해 서버 설문 조사"대안을 알고 있습니다 (지금 내가하고있는 일입니다). 이 문제의 주된 문제점 (복잡한 서버 측 코드 제외)은 일반적으로 큰 파일을 업로드하는 동안 대부분의 ISP가 열악한 업스트림을 제공하기 때문에 사용자 연결이 완전히 제한된다는 것입니다. 따라서 추가 요청을하는 것은 내가 바라는 것처럼 반응하지 않습니다. 브라우저가 항상 가지고있는이 정보를 얻는 방법 (비표준)이 있기를 바랐습니다.
업로드 된 바이트의 경우 매우 쉽습니다. 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();
}
Firefox는 XHR 다운로드 진행 이벤트를 지원 합니다 .
AJAX 패턴에 대한 진행률 표시기에 대한 좋은 설명이 있습니다.
http://ajaxpatterns.org/Progress_Indicator
가장 유망한 접근법 중 하나는 서버로 다시 두 번째 통신 채널을 열어서 얼마나 많은 전송이 완료되었는지 묻는 것 같습니다.
Firefox 3.5는 업로드 진행 이벤트를 지원합니다
전체 업로드의 경우 처리 방법이없는 것 같지만 다운로드하려는 것과 비슷한 것이 있습니다. readyState가 3이면, responseText를 주기적으로 쿼리하여 String으로 다운로드 한 모든 컨텐츠를 가져옵니다 (IE에서는 작동하지 않음). 모든 시점에서 readyState 4로 전환 될 때까지 모든 컨텐츠를 사용할 수 있습니다. 주어진 시간에 다운로드 된 바이트는 responseText에 저장된 문자열의 총 바이트와 같습니다.
For a all or nothing approach to the upload question, since you have to pass a string for upload (and it's possible to determine the total bytes of that) the total bytes sent for readyState 0 and 1 will be 0, and the total for readyState 2 will be the total bytes in the string you passed in. The total bytes both sent and received in readyState 3 and 4 will be the sum of the bytes in the original string plus the total bytes in responseText.
<!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>
If you have access to your apache install and trust third-party code, you can use the apache upload progress module (if you use apache; there's also a nginx upload progress module).
Otherwise, you'd have to write a script that you can hit out of band to request the status of the file (checking the filesize of the tmp file for instance).
There's some work going on in firefox 3 I believe to add upload progress support to the browser, but that's not going to get into all the browsers and be widely adopted for a while (more's the pity).
The only way to do that with pure javascript is to implement some kind of polling mechanism. You will need to send ajax requests at fixed intervals (each 5 seconds for example) to get the number of bytes received by the server.
A more efficient way would be to use flash. The flex component FileReference dispatchs periodically a 'progress' event holding the number of bytes already uploaded. If you need to stick with javascript, bridges are available between actionscript and javascript. The good news is that this work has been already done for you :)
This library allows to register a javascript handler on the flash progress event.
This solution has the hudge advantage of not requiring aditionnal resources on the server side.
참고URL : https://stackoverflow.com/questions/76976/how-to-get-progress-from-xmlhttprequest
'programing tip' 카테고리의 다른 글
__init__ 외부에 정의 된 인스턴스 속성 attribute_name (0) | 2020.07.01 |
---|---|
BREW 설치 시간이 너무 많이 걸리는 gcc (0) | 2020.07.01 |
Javascript의 문자열에서 $ {} (달러 기호 및 중괄호)의 의미는 무엇입니까? (0) | 2020.07.01 |
Java Reflection : 변수 이름을 얻는 방법? (0) | 2020.07.01 |
데이터 매퍼, 테이블 데이터 게이트웨이 (게이트웨이), 데이터 액세스 개체 (DAO) 및 리포지토리 패턴의 차이점은 무엇입니까? (0) | 2020.07.01 |