Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 949
Sam Lee Avatar asked Jun 25 '15 22:06

Sam Lee


People also ask

How do I terminate HTTP request?

You can abort the current HTTP request using the abort() method, i.e., after invoking this method, on a particular request, execution of it will be aborted. If this method is invoked after one execution, responses of that execution will not be affected and the subsequent executions will be aborted.

Is fetch an HTTP request?

The Fetch API is a modern interface that allows you to make HTTP requests to servers from web browsers.

How does abort controller work?

The AbortController interface represents a controller object that allows you to abort one or more Web requests as and when desired. You can create a new AbortController object using the AbortController() constructor. Communicating with a DOM request is done using an AbortSignal object.


2 Answers

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+):

<script>      // 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()      }    </script>        <h1>Example of fetch abort</h1>  <hr>  <button onclick="beginFetching();">      Begin  </button>  <button onclick="abortFetching();">      Abort  </button>

Sources:

  • The final version of AbortController has been added to the DOM specification
  • The corresponding PR for the fetch specification is now merged.
  • Browser bugs tracking the implementation of AbortController is available here: Firefox: #1378342, Chromium: #750599, WebKit: #174980, Edge: #13009916.
like image 117
SudoPlz Avatar answered Sep 19 '22 02:09

SudoPlz


https://developers.google.com/web/updates/2017/09/abortable-fetch

https://dom.spec.whatwg.org/#aborting-ongoing-activities

// setup AbortController const controller = new AbortController(); // signal to pass to fetch const signal = controller.signal;  // fetch as usual fetch(url, { signal }).then(response => {   ... }).catch(e => {   // catch the abort if you like   if (e.name === 'AbortError') {     ...   } });  // when you want to abort controller.abort(); 

works in edge 16 (2017-10-17), firefox 57 (2017-11-14), desktop safari 11.1 (2018-03-29), ios safari 11.4 (2018-03-29), chrome 67 (2018-05-29), and later.


on older browsers, you can use github's whatwg-fetch polyfill and AbortController polyfill. you can detect older browsers and use the polyfills conditionally, too:

import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only' import {fetch} from 'whatwg-fetch'  // use native browser implementation if it supports aborting const abortableFetch = ('signal' in new Request('')) ? window.fetch : fetch 
like image 21
Jayen Avatar answered Sep 20 '22 02:09

Jayen