How do I cancel an HTTP fetch() request?

前端 未结 6 1688
小蘑菇
小蘑菇 2020-11-22 14:58

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

6条回答
  •  深忆病人
    2020-11-22 15:23

    As of Feb 2018, fetch() can be cancelled with the code below on Chrome (read Using Readable Streams to enable Firefox support). No error is thrown for catch() to pick up, and this is a temporary solution until AbortController is fully adopted.

    fetch('YOUR_CUSTOM_URL')
    .then(response => {
      if (!response.body) {
        console.warn("ReadableStream is not yet supported in this browser.  See https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream")
        return response;
      }
    
      // get reference to ReadableStream so we can cancel/abort this fetch request.
      const responseReader = response.body.getReader();
      startAbortSimulation(responseReader);
    
      // Return a new Response object that implements a custom reader.
      return new Response(new ReadableStream(new ReadableStreamConfig(responseReader)));
    })
    .then(response => response.blob())
    .then(data => console.log('Download ended. Bytes downloaded:', data.size))
    .catch(error => console.error('Error during fetch()', error))
    
    
    // Here's an example of how to abort request once fetch() starts
    function startAbortSimulation(responseReader) {
      // abort fetch() after 50ms
      setTimeout(function() {
        console.log('aborting fetch()...');
        responseReader.cancel()
        .then(function() {
          console.log('fetch() aborted');
        })
      },50)
    }
    
    
    // ReadableStream constructor requires custom implementation of start() method
    function ReadableStreamConfig(reader) {
      return {
        start(controller) {
          read();
          function read() {
            reader.read().then(({done,value}) => {
              if (done) {
                controller.close();
                return;
              }
              controller.enqueue(value);
              read();
            })
          }
        }
      }
    }
    

提交回复
热议问题