평범한 자바 스크립트에서는 매우 간단합니다. {XMLHTTPRequest}.onprogress
var xhr = new XMLHttpRequest();
xhr.onprogress = function(e){
if (e.lengthComputable)
var percent = (e.loaded / e.total) * 100;
};
xhr.open('GET', 'http://www...', true);
xhr.onreadystatechange = function() {
...
};
xhr.send(null);
하지만 JQuery ( $.get()
또는 $.ajax()
)로 html 데이터를 다운로드하는 ajax 사이트를 만들고 있는데, 작은 진행률 표시 줄로 표시하기 위해 요청의 진행 상황을 얻는 가장 좋은 방법이 무엇인지 궁금합니다. JQuery 문서에서 유용한 것을 찾는 중 …
답변
다음과 같은 것 $.ajax
(HTML5 만 해당) :
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with upload progress here
}
}, false);
xhr.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with download progress
}
}, false);
return xhr;
},
type: 'POST',
url: "/",
data: {},
success: function(data){
//Do something on success
}
});
답변
jQuery는 이미 promise를 구현 했으므로이 기술을 사용하고 이벤트 논리를 options
매개 변수 로 이동하지 않는 것이 좋습니다 . 진행률 약속을 추가하는 jQuery 플러그인을 만들었고 이제 다른 약속처럼 사용하기 쉽습니다.
$.ajax(url)
.progress(function(){
/* do some actions */
})
.progressUpload(function(){
/* do something on uploading */
});
github 에서 확인하세요
답변
Ajax 객체의 구성을 가로채는 세 가지 방법을 시도했습니다.
- 내 첫 번째 시도는를 사용
xhrFields
했지만 한 명의 리스너 만 허용하고 다운로드 (업로드 아님) 진행률에만 첨부하고 불필요한 복사 및 붙여 넣기처럼 보이는 것이 필요합니다. - 두 번째 시도
progress
는 반환 된 promise에 함수를 추가했지만, 고유 한 핸들러 배열을 유지해야했습니다. 한 곳에서는 XHR에 액세스하고 다른 곳에서는 jQuery XHR에 액세스 할 수 있었지만 지연된 객체에는 액세스 할 수 없었기 때문에 핸들러를 연결할 좋은 객체를 찾을 수 없었습니다 (그 약속 만 해당). - 세 번째 시도로 핸들러를 첨부하기 위해 XHR에 직접 액세스 할 수 있었지만 코드 복사 및 붙여 넣기가 많이 필요했습니다.
- 세 번째 시도를 마무리하고 jQuery
ajax
를 내 것으로 교체했습니다 . 유일한 잠재적 인 단점은 더 이상 자신의xhr()
설정을 사용할 수 없다는 것 입니다.options.xhr
함수 인지 확인하여이를 허용 할 수 있습니다 .
나중에 쉽게 찾을 수 있도록 실제로 promise.progress
함수를 호출 xhrProgress
합니다. 업로드 및 다운로드 리스너를 구분하기 위해 다른 이름을 지정할 수 있습니다. 원래 포스터가 이미 필요한 것을 얻었더라도 누군가에게 도움이되기를 바랍니다.
(function extend_jQuery_ajax_with_progress( window, jQuery, undefined )
{
var $originalAjax = jQuery.ajax;
jQuery.ajax = function( url, options )
{
if( typeof( url ) === 'object' )
{options = url;url = undefined;}
options = options || {};
// Instantiate our own.
var xmlHttpReq = $.ajaxSettings.xhr();
// Make it use our own.
options.xhr = function()
{return( xmlHttpReq );};
var $newDeferred = $.Deferred();
var $oldPromise = $originalAjax( url, options )
.done( function done_wrapper( response, text_status, jqXHR )
{return( $newDeferred.resolveWith( this, arguments ));})
.fail( function fail_wrapper( jqXHR, text_status, error )
{return( $newDeferred.rejectWith( this, arguments ));})
.progress( function progress_wrapper()
{
window.console.warn( "Whoa, jQuery started actually using deferred progress to report Ajax progress!" );
return( $newDeferred.notifyWith( this, arguments ));
});
var $newPromise = $newDeferred.promise();
// Extend our own.
$newPromise.progress = function( handler )
{
xmlHttpReq.addEventListener( 'progress', function download_progress( evt )
{
//window.console.debug( "download_progress", evt );
handler.apply( this, [evt]);
}, false );
xmlHttpReq.upload.addEventListener( 'progress', function upload_progress( evt )
{
//window.console.debug( "upload_progress", evt );
handler.apply( this, [evt]);
}, false );
return( this );
};
return( $newPromise );
};
})( window, jQuery );
답변
jQuery에는 모든 ajax 호출 과 AjaxSetup()
같은 전역 ajax 핸들러를 등록 beforeSend
하고 원하는 진행을 수행하기 위해 객체에 complete
액세스 xhr
할 수있는 기능이 있습니다.
답변
http://www.htmlgoodies.com/beyond/php/show-progress-report-for-long-running-php-scripts.html
비슷한 솔루션을 찾고 있었는데이 솔루션이 완전히 사용되었습니다.
var es;
function startTask() {
es = new EventSource('yourphpfile.php');
//a message is received
es.addEventListener('message', function(e) {
var result = JSON.parse( e.data );
console.log(result.message);
if(e.lastEventId == 'CLOSE') {
console.log('closed');
es.close();
var pBar = document.getElementById('progressor');
pBar.value = pBar.max; //max out the progress bar
}
else {
console.log(response); //your progress bar action
}
});
es.addEventListener('error', function(e) {
console.log('error');
es.close();
});
}
및 서버 출력
header('Content-Type: text/event-stream');
// recommended to prevent caching of event data.
header('Cache-Control: no-cache');
function send_message($id, $message, $progress) {
$d = array('message' => $message , 'progress' => $progress); //prepare json
echo "id: $id" . PHP_EOL;
echo "data: " . json_encode($d) . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
//LONG RUNNING TASK
for($i = 1; $i <= 10; $i++) {
send_message($i, 'on iteration ' . $i . ' of 10' , $i*10);
sleep(1);
}
send_message('CLOSE', 'Process complete');
답변
Ajax 요청 진행 상황을 표시하려면 다음 단계를 따르십시오.
- Html 및 CSS를 사용하여 Spinner를 만들거나 Bootstrap Spinner를 사용합니다.
- 최종 사용자가 무한 루프 또는 임계 값 제한 시간에 대해 AJAX 데이터를 요청할 때 Spinner를 표시합니다.
- 따라서 AJAX 요청의 SUCCESS / ERROR 결과 후에 현재 표시된 Spinner를 제거하고 결과를 표시하십시오.
쉽게하기 위해이 목적을 위해 스피너를 동적으로 표시하고 숨기는 데 JS 클래스를 사용하는 것이 좋습니다.
이게 도움이 되길 바란다!