onload가 XMLHttpRequest에서 readyState == 4와 같습니까?


122

xhr 반환 이벤트에 대해 혼란 스럽습니다. 내가 알 수 있듯이 onreadystatechange-> readyState == 4 와 onload 사이에는 크게 다르지 않습니다. 사실입니까?

var xhr = new XMLHttpRequest();
xhr.open("Get", url, false);
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4)
    {
        /* do some thing*/
    }
};

xhr.send(null);

또는

xhr.onload = function() { /* do something */ }

13
누군가 이것을 예제로보고 있다면 async = false (xhr.open의 세 번째 인수)를 사용하고 있다는 점에 유의하십시오. 이것은 일반적으로 원하는 것이 아닙니다.
eddiewould

답변:


65

동일해야합니다. onloadXMLHttpRequest 2에 추가 onreadystatechange되었지만 원래 사양 이후에있었습니다.


onload를 사용할 때 모바일 Safari가 돌아 오지 않는 것 같습니다. 하지만 onreadystatechange는 작동합니다.
Kai Hartmann 2014 년

1
더 이상 XHR 1과 XHR 2 사이에 명확한 구분이 없으며 하나의 표준으로 통합되었습니다. XHR 2를 대표하는 가장 일반적인 기능은 CORS 지원이므로 그 관점에서 XHR 2는 IE 10까지 IE에 나타나지 않았지만 XHR.onload는 일반적으로 XHR 1로 여겨지는 IE 9에서 지원되었습니다.
Chase

153

이것은 거의 항상 사실입니다. 그러나 한 가지 중요한 차이점 은 핸들러가 일반적으로 트리거되는 경우 (일반적으로 네트워크 연결 문제) onreadystatechange에서도 이벤트 핸들러가 트리거 된다는 것 입니다. 이 경우 상태가 0이됩니다. 최신 Chrome, Firefox 및 IE에서이 문제가 발생하는지 확인했습니다.readyState==4onerror

따라서 onerror최신 브라우저를 사용 하고 대상으로하는 경우에는 사용 onreadystatechange해서는 안되지만 onload대신 사용해야 합니다. 이는 HTTP 요청이 성공적으로 완료되었을 때 (실제 응답 및 상태 코드 포함) 호출되는 것으로 보장되는 것 같습니다. 그렇지 않으면 오류가 발생한 경우 두 개의 이벤트 핸들러가 트리거 될 수 있습니다 (이 특별한 경우에 대해 경험적으로 알아 낸 방법입니다).

다음은 내가 작성한 Plunker 테스트 프로그램에 대한 링크 입니다.이를 통해 다양한 URL을 테스트 readyState하고 다양한 경우에서 JavaScript 앱에서 볼 수있는 이벤트 및 값 의 실제 시퀀스 를 볼 수 있습니다. JS 코드도 아래에 나열되어 있습니다.

var xhr;
function test(url) {
    xhr = new XMLHttpRequest();
    xhr.addEventListener("readystatechange", function() { log(xhr, "readystatechange") });
    xhr.addEventListener("loadstart", function(ev) { log(xhr, "loadstart", ev.loaded + " of " + ev.total) });
    xhr.addEventListener("progress", function(ev) { log(xhr, "progress", ev.loaded + " of " + ev.total) });
    xhr.addEventListener("abort", function() { log(xhr, "abort") });
    xhr.addEventListener("error", function() { log(xhr, "error") });
    xhr.addEventListener("load", function() { log(xhr, "load") });
    xhr.addEventListener("timeout", function(ev) { log(xhr, "timeout", ev.loaded + " of " + ev.total) });
    xhr.addEventListener("loadend", function(ev) { log(xhr, "loadend", ev.loaded + " of " + ev.total) });
    xhr.open("GET", url);
    xhr.send();
}

function clearLog() {
    document.getElementById('log').innerHTML = '';
}

function logText(msg) {
    document.getElementById('log').innerHTML += msg + "<br/>";
}

function log(xhr, evType, info) {
    var evInfo = evType;
    if (info)
        evInfo += " - " + info ;
    evInfo += " - readyState: " + xhr.readyState + ", status: " + xhr.status;
    logText(evInfo);
}

function selected(radio) {
    document.getElementById('url').value = radio.value;
}

function testUrl() {
    clearLog();
    var url = document.getElementById('url').value;
    if (!url)
        logText("Please select or type a URL");
    else {
        logText("++ Testing URL: " + url);
        test(url);
    }
}

function abort() {
    xhr.abort();
}

2
내부를 명확히하기 위해 @Fernando onload, readyState === 4진정한 권리를 보장합니까?
kgf3JfUtW

6
@sam 예, 그 반대는 분명히 사실이 아니지만 항상 그렇습니다 . readyState4 on error또는 abort케이스도 마찬가지입니다. 이 상태는 기본적으로로드 프로세스가 성공적으로 완료되었는지 여부를 의미합니다. 정상적이고 성공적인로드의 경우 최종 이벤트 시퀀스는 progress(모든 데이터가로드 됨), readystatechange(함께 readyState == 4) load,, loadend.
Fernando Echeverria

2
다음 onload경우에도 트리거되지 않습니다.No 'Access-Control-Allow-Origin' header is present on the requested resource.
deathangel908

사실입니다. 이것이 onerror핸들러 를 트리거하는 경우 중 하나입니다 .
페르난도 에체베리아

1
@Pacerier : 예, 여기를 참조하십시오 : plnkr 테스트
Fernando Echeverria

10

아니요, 동일하지 않습니다. 네트워크 오류가 발생하거나 작업을 중단하면 onload이 호출되지 않습니다. 실제로 가장 가까운 이벤트 readyState === 4loadend. 흐름은 다음과 같습니다.

     onreadystatechange
      readyState === 4
             
 onload / onerror / onabort
             
         onloadend
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.