javascriptajaxfetch-api

How do I cancel an HTTP fetch() request?


There is a new API for making requests from JavaScript: fetch(). Is there any built in mechanism for canceling these requests in-flight?


Solution

  • TL/DR:

    fetch now supports a signal parameter as of 20 September 2017, but not all browsers seem support this at the moment.

    2020 UPDATE: Most major browsers (Edge, Firefox, Chrome, Safari, Opera, and a few others) support the feature, which has become part of the DOM living standard. (as of 5 March 2020)

    This is a change we will be seeing very soon though, and so you should be able to cancel a request by using an AbortControllers AbortSignal.

    Long Version

    How to:

    The way it works is this:

    Step 1: You create an AbortController (For now I just used this)

    const controller = new AbortController()
    

    Step 2: You get the AbortControllers signal like this:

    const signal = controller.signal
    

    Step 3: You pass the signal to fetch like so:

    fetch(urlToFetch, {
        method: 'get',
        signal: signal, // <------ This is our AbortSignal
    })
    

    Step 4: Just abort whenever you need to:

    controller.abort();
    

    Here's an example of how it would work (works on Firefox 57+):

    // Create an instance.
    const controller = new AbortController()
    const signal = controller.signal
    
    /*
    // Register a listenr.
    signal.addEventListener("abort", () => {
        console.log("aborted!")
    })
    */
    
    
    function beginFetching() {
      console.log('Now fetching');
      var urlToFetch = "https://httpbin.org/delay/3";
    
      fetch(urlToFetch, {
          method: 'get',
          signal: signal,
        })
        .then(function(response) {
          console.log(`Fetch complete. (Not aborted)`);
        }).catch(function(err) {
          console.error(` Err: ${err}`);
        });
    }
    
    
    function abortFetching() {
      console.log('Now aborting');
      // Abort.
      controller.abort()
    }
    <h1>Example of fetch abort</h1>
    <hr>
    <button onclick="beginFetching();">Begin</button>
    <button onclick="abortFetching();">Abort</button>

    Sources: