jQuery를 사용하여 Ajax 요청 중단


1827

jQuery를 사용하여 아직 응답을받지 못한 Ajax 요청취소 / 취소하려면 어떻게 해야합니까?


2
어쩌면 나는 그 질문을 오해했지만, 당신은 단순히 사용할 수 없었 $.ajaxStop습니까?
Luke Madhanga

17
@LukeMadhanga; 생각 ajaxStop만 모든 AJAX 요청이 완료되면,이 요청을 중지하지 않습니다 감지합니다. 내 경험상, 당신은 이것을 다음과 같이 사용할 것입니다 : $(document).ajaxStop(function(){alert("All done")}). 사용하는 .abort()것이 가장 좋습니다.
TheCarver

답변:


1744

대부분의 jQuery Ajax 메소드는 XMLHttpRequest (또는 이와 동등한) 객체를 리턴하므로을 사용할 수있다 abort().

설명서를 참조하십시오.

  • 중단 방법 ( MSDN ). 현재 HTTP 요청을 취소합니다.
  • abort () ( MDN ). 요청이 이미 전송 된 경우이 메소드는 요청을 중단합니다.
var xhr = $.ajax({
    type: "POST",
    url: "some.php",
    data: "name=John&location=Boston",
    success: function(msg){
       alert( "Data Saved: " + msg );
    }
});

//kill the request
xhr.abort()

업데이트 : jQuery 1.5부터 반환 된 객체는 jqXHR이라는 기본 XMLHttpRequest 객체의 래퍼입니다. 이 개체는 모든 기본 속성과 메서드를 노출시키는 것으로 보이므로 위 예제는 여전히 작동합니다. jqXHR 객체 (jQuery API 설명서)를 참조하십시오 .

업데이트 2 : jQuery 3부터 ajax 메소드는 이제 중단과 같은 추가 메소드를 사용하여 promise를 반환하므로 반환되는 객체가 xhr더 이상 아니지만 위의 코드는 여전히 작동합니다 . 3.0 블로그를 참조 하십시오 .

업데이트 3 : xhr.abort()여전히 jQuery 3.x에서 작동합니다. 업데이트 2 가 올바른 것으로 가정하지 마십시오 . jQuery Github 저장소에 대한 추가 정보 .


12
브라우저에서 '중지'버튼을 클릭하는 것과 같습니다. 요청을 취소합니다. 그런 다음 다른 요청에 동일한 XHR 객체를 재사용 할 수 있습니다.
meouw

65
@brad 불행히도 abort서버와의 연결을 닫지 않으므로 success여전히 호출됩니다. 이것은 긴 폴링을 가진 Comet의 구현에 매우 문제가됩니다.
pepkin88

6
@ErvWalter 이전 요청을 취소하는 다른 요청을 전달할 수 있습니다.
Asad Saeeduddin

8
필자의 테스트에서는 브라우저에서 요청이 중단되었지만 .fail () 메서드는 jqXHR, status = 0, jqXHR, statusMessage = "abort"로 호출됩니다.
BJ Safdie

9
.abort()jQuery 3.2.1에서 여전히 작동합니다. jQuery 핵심 팀 구성원 의 관련 github 문제 에 대한 이 의견은 이 답변이 잘못되어 .abort() 제거되지 않았 음 을 암시하는 것으로 보입니다 .
alarive

117

요청을 불러올 수는 없지만 응답이 무시되는 시간 초과 값을 설정할 수 있습니다. jquery AJAX 옵션에 대해서는이 페이지 를 참조하십시오 . 시간 초과 기간이 초과되면 오류 콜백이 호출됩니다. 모든 AJAX 요청에는 이미 기본 시간 초과가 있습니다.

요청 오브젝트 에서 abort () 메소드를 사용할 수도 있지만, 클라이언트가 이벤트 수신을 중지하게하지만 서버가 처리를 중지하지 않을 수도 있습니다 .


74

그것은의 비동기 거기의 보낸 된 후에는 의미 요청.

서버가 AJAX 요청으로 인해 비용이 많이 드는 작업을 시작하는 경우 취소 요청을 수신하기 위해 서버를 열고 별도의 AJAX 요청을 보내서 서버에서 수행중인 작업을 중지하는 것이 가장 좋습니다.

그렇지 않으면 단순히 AJAX 응답을 무시하십시오.


48
이 문맥에서 비동기는 단순히 요청이 스크립트의 흐름을 방해하지 않음을 의미합니다. 브라우저는 이제 요청이 완료되기 전에 요청을 조기에 중단 할 수 있습니다.
ElephantHunter

4
서버에 취소 요청을 보내려면 어떻게해야합니까? 서버가 처리 중지 요청을 어떻게 알 수 있는지 이해하지 못합니까? 예를 들어 주시겠습니까? 감사합니다.
Lucky Soni

3
@LuckySoni, Elephanthunter는 고객 측에서만 논의합니다. 서버는 .abort 요청의 영향을받지 않습니다
Kloar

4
@Kloar, 요청이 아직 서버에 의해 수신되지 않으면 (f.ex. 대규모 멀티 파트 요청), 클라이언트가 소켓을 닫을 수 있으며 서버가 영향을받습니다.
white

4
PHP는 자동으로 중단 된 요청을 확인하고 자동으로 종료됩니다. php.net/manual/en/function.ignore-user-abort.php
hanshenrik

68

호출 한 내용을 배열에 저장 한 다음 각각에 대해 xhr.abort ()를 호출하십시오.

거대한 경고 : 요청을 중단 할 수는 있지만 클라이언트 측뿐입니다. 서버 측에서 여전히 요청을 처리 중일 수 있습니다. 세션 데이터와 함께 PHP 또는 ASP와 같은 것을 사용하는 경우 세션 데이터는 ajax가 완료 될 때까지 잠 깁니다. 따라서 사용자가 웹 사이트를 계속 탐색 할 수있게하려면 session_write_close () 를 호출해야합니다 . 세션을 저장하고 잠금을 해제하여 계속 대기중인 다른 페이지가 진행되도록합니다. 이것이 없으면 여러 페이지가 잠금이 제거되기를 기다릴 수 있습니다.


항상 이전 것을 취소하기 때문에 항상 그렇게 할 수는 없습니까? (배열을 사용할 필요가 없음)
비극성

60

AJAX 요청은 시작된 순서대로 완료되지 않을 수 있습니다. 중단하는 대신 최신 AJAX 응답을 제외한 모든 AJAX 응답 을 무시 하도록 선택할 수 있습니다 .

  • 카운터 만들기
  • AJAX 요청을 시작할 때 카운터 증가
  • 카운터의 현재 값을 사용하여 요청을 "스탬프"
  • 성공 콜백에서 스탬프를 카운터와 비교하여 가장 최근 요청인지 확인하십시오.

대략적인 코드 개요 :

var xhrCount = 0;
function sendXHR() {
    // sequence number for the current invocation of function
    var seqNumber = ++xhrCount;
    $.post("/echo/json/", { delay: Math.floor(Math.random() * 5) }, function() {
        // this works because of the way closures work
        if (seqNumber === xhrCount) {
            console.log("Process the response");
        } else {
            console.log("Ignore the response");
        }
    });
}
sendXHR();
sendXHR();
sendXHR();
// AJAX requests complete in any order but only the last 
// one will trigger "Process the response" message

jsFiddle 데모


XHR 요청을 취소해야한다는 경고 (이 페이지의 다른 주석 참조)로 인해 이것이 가장 좋고 간단한 옵션 일 것입니다.
Quinn Comendant

41

우리는이 문제를 해결하기 위해 3 가지 접근법을 테스트했습니다.

  1. @meouw가 제안한대로 요청을 취소합니다.
  2. 모든 요청을 실행하지만 마지막 제출 결과 만 처리
  3. 다른 요청이 여전히 보류중인 한 새로운 요청을 방지합니다.

var Ajax1 = {
  call: function() {
    if (typeof this.xhr !== 'undefined')
      this.xhr.abort();
    this.xhr = $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        //process response
      }
    });
  }
};
var Ajax2 = {
  counter: 0,
  call: function() {
    var self = this,
      seq = ++this.counter;
    $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        if (seq === self.counter) {
          //process response
        }
      }
    });
  }
};
var Ajax3 = {
  active: false,
  call: function() {
    if (this.active === false) {
      this.active = true;
      var self = this;
      $.ajax({
        url: 'your/long/running/request/path',
        type: 'GET',
        success: function(data) {
          //process response
        },
        complete: function() {
          self.active = false;
        }
      });
    }
  }
};
$(function() {
  $('#button').click(function(e) {
    Ajax3.call();
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="button" type="button" value="click" />

우리의 경우 우리는 서버에 대한로드를 줄이면서 접근법 3을 사용하기로 결정했습니다. 그러나 jQuery가 .complete () 메서드의 호출을 보장하는지 확실하지 않으면 교착 상태가 발생할 수 있습니다. 테스트에서 우리는 그러한 상황을 재현 할 수 없었습니다.


36

항상 이런 식으로하는 것이 가장 좋습니다.

var $request;
if ($request != null){ 
    $request.abort();
    $request = null;
}

$request = $.ajax({
    type : "POST", //TODO: Must be changed to POST
    url : "yourfile.php",
    data : "data"
    }).done(function(msg) {
        alert(msg);
    });

그러나 if 문을 검사하여 ajax 요청이 null인지 아닌지를 확인하는 것이 훨씬 좋습니다.


2
또한 요청이 이미 실행 중인지 확인하지만 부울을 사용합니다.
여기를 클릭하십시오

15

xhr에게 전화하십시오. jquery ajax 객체인지 또는 네이티브 XMLHTTPRequest 객체인지 여부를 abort () .

예:

//jQuery ajax
$(document).ready(function(){
    var xhr = $.get('/server');
    setTimeout(function(){xhr.abort();}, 2000);
});

//native XMLHTTPRequest
var xhr = new XMLHttpRequest();
xhr.open('GET','/server',true);
xhr.send();
setTimeout(function(){xhr.abort();}, 2000);

13

라이브 검색 솔루션을 사용하고 있었으며 최근 / 최근 요청보다 오래 걸릴 수있는 보류중인 요청을 취소해야했습니다.

내 경우에는 다음과 같이 사용했습니다.

//On document ready
var ajax_inprocess = false;

$(document).ajaxStart(function() {
ajax_inprocess = true;
});

$(document).ajaxStop(function() {
ajax_inprocess = false;
});

//Snippet from live search function
if (ajax_inprocess == true)
{
    request.abort();
}
//Call for new request 

12

스레드의 많은 사람들이 지적했듯이 요청이 클라이언트 측에서 중단 되었기 때문에 서버는 여전히 요청을 처리합니다. 프런트 엔드에서 수신 대기하는 작업을 수행하고 있기 때문에 서버에 불필요한로드가 발생합니다.

내가 해결하려고했던 문제 (다른 사람들도 실행할 수 있음)는 사용자가 입력 필드에 정보를 입력했을 때 Google Instant 유형의 느낌 요청을 시작하고 싶었다는 것입니다.

불필요한 요청이 발생하지 않도록하고 프런트 엔드의 급격한 유지를 위해 다음을 수행했습니다.

var xhrQueue = [];
var xhrCount = 0;

$('#search_q').keyup(function(){

    xhrQueue.push(xhrCount);

    setTimeout(function(){

        xhrCount = ++xhrCount;

        if (xhrCount === xhrQueue.length) {
            // Fire Your XHR //
        }

    }, 150);

});

이것은 기본적으로 150ms마다 하나의 요청을 보냅니다 (자신의 필요에 맞게 사용자 지정할 수있는 변수). 당신은 문제가 정확히 여기 무슨 일이 일어나고 있는지 이해하는 데 문제가있는 경우, 로그인 xhrCountxhrQueue단지의 경우 블록 전에 콘솔에.


11

예를 들어 ajax.abort ()를 사용하십시오. 예를 들어 다음과 같은 다른 요청을 보내기 전에 보류중인 ajax 요청을 중단 할 수 있습니다

//check for existing ajax request
if(ajax){ 
 ajax.abort();
 }
//then you make another ajax request
$.ajax(
 //your code here
  );

11

이것을 사용하여 지속적인 아약스 호출을 중단 할 수 있습니다

<input id="searchbox" name="searchbox" type="text" />

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>

<script type="text/javascript">
     var request = null;
        $('#searchbox').keyup(function () {
            var id = $(this).val();
            request = $.ajax({
                type: "POST", //TODO: Must be changed to POST
                url: "index.php",
                data: {'id':id},
                success: function () {

                },
                beforeSend: function () {
                    if (request !== null) {
                        request.abort();
                    }
                }
            });
        });

</script>

10

신뢰할 수있는 방법은 없으며 요청이 이동하면 시도조차하지 않습니다. 합리적으로 반응 하는 유일한 방법은 반응을 무시 하는 것입니다.

대부분의 경우 다음과 같은 상황에서 발생할 수 있습니다 : 사용자가 많은 연속 XHR을 트리거하는 버튼을 너무 자주 클릭합니다. 여기에는 많은 옵션이 있습니다 .XHR이 반환 될 때까지 버튼을 차단하거나 다른 XHR이 힌트를 실행하는 동안 새 XHR을 트리거하지 않습니다 사용자는 몸을 뒤로 젖히거나 보류중인 XHR 응답을 제외한 모든 것을 폐기합니다.


7

다음 코드는 Ajax 요청 시작 및 중단을 보여줍니다.

function libAjax(){
  var req;
  function start(){

  req =    $.ajax({
              url: '1.php',
              success: function(data){
                console.log(data)
              }
            });

  }

  function stop(){
    req.abort();
  }

  return {start:start,stop:stop}
}

var obj = libAjax();

 $(".go").click(function(){


  obj.start();


 })



 $(".stop").click(function(){

  obj.stop();


 })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" class="go" value="GO!" >
   <input type="button" class="stop" value="STOP!" >

5
이것이 어떻게 문제를 해결하는지 설명해주세요. 이것은 OP와 다른 미래의 검색 자들에게 도움이 될 것입니다.
SnareChops

5

폴링 문제가 있었고 페이지가 닫히면 폴링이 계속되어 내 원인으로 인해 페이지가 닫힌 후 다음 50 초 동안 mysql 값이 설정되어 사용자가 업데이트를 놓칠 수 있습니다. 아약스 요청을 죽 였음에도 불구하고 $ _SESSION을 사용하여 var가 끝날 때까지 자체 업데이트를하지 않고 새로운 것이 시작될 때까지 설정하지 않았으므로 데이터베이스에서 값을 0 = offpage로 설정했습니다. 폴링 해당 행을 쿼리하고 false를 반환합니다. 폴링에서 쿼리하면 분명히 현재 값을 얻을 때 0 일 때 ...

이것이 도움이 되었기를 바랍니다.


5

만약 xhr.abort(); 원인 페이지를 다시로드,

그런 다음 onreadystatechange중단 전에 설정 하여 다음 을 방지 할 수 있습니다 .

// ↓ prevent page reload by abort()
xhr.onreadystatechange = null;
// ↓ may cause page reload
xhr.abort();

4

미리 정의 된 대기 시간 내에 서버에서 데이터가 반환되지 않는 경우 AJAX 요청을 취소하는 방법을 보여주는 데모 를 공유했습니다 .

HTML :

<div id="info"></div>

JS 코드 :

var isDataReceived= false, waitTime= 1000; 
$(function() {
    // Ajax request sent.
     var xhr= $.ajax({
      url: 'http://api.joind.in/v2.1/talks/10889',
      data: {
         format: 'json'
      },     
      dataType: 'jsonp',
      success: function(data) {      
        isDataReceived= true;
        $('#info').text(data.talks[0].talk_title);        
      },
      type: 'GET'
   });
   // Cancel ajax request if data is not loaded within 1sec.
   setTimeout(function(){
     if(!isDataReceived)
     xhr.abort();     
   },waitTime);   
});

1
$.ajaxtimeout직접 작성할 필요가없는 옵션을 제공합니다 . 간단하게 사용하십시오 ..., data: {...}, timeout: waitTime,....
Bram Vanroy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.