Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/448.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何取消HTTP fetch()请求?_Javascript_Ajax_Fetch Api - Fatal编程技术网

Javascript 如何取消HTTP fetch()请求?

Javascript 如何取消HTTP fetch()请求?,javascript,ajax,fetch-api,Javascript,Ajax,Fetch Api,有一个新的API用于从JavaScript发出请求:fetch()。是否有任何内置机制可以在飞行中取消这些请求?正如@spro所说,目前还没有合适的解决方案 但是,如果您有飞行中的响应并且正在使用ReadableStream,则可以关闭流以取消请求 fetch('http://example.com').then((res) => { const reader = res.body.getReader(); /* * Your code for reading stream

有一个新的API用于从JavaScript发出请求:fetch()。是否有任何内置机制可以在飞行中取消这些请求?

正如@spro所说,目前还没有合适的解决方案

但是,如果您有飞行中的响应并且正在使用ReadableStream,则可以关闭流以取消请求

fetch('http://example.com').then((res) => {
  const reader = res.body.getReader();

  /*
   * Your code for reading streams goes here
   */

  // To abort/cancel HTTP request...
  reader.cancel();
});

正如@spro所说,目前还没有合适的解决方案

但是,如果您有飞行中的响应并且正在使用ReadableStream,则可以关闭流以取消请求

fetch('http://example.com').then((res) => {
  const reader = res.body.getReader();

  /*
   * Your code for reading streams goes here
   */

  // To abort/cancel HTTP request...
  reader.cancel();
});

//安装程序中止控制器
const controller=new AbortController();
//传来取回的信号
常数信号=控制器信号;
//照常取
获取(url,{signal})。然后(响应=>{
...
}).catch(e=>{
//如果你愿意的话,请点击中止
如果(e.name=='abortorror'){
...
}
});
//当你想中止时
controller.abort();
适用于edge 16(2017-10-17)、firefox 57(2017-11-14)、桌面safari 11.1(2018-03-29)、ios safari 11.4(2018-03-29)、chrome 67(2018-05-29)和更高版本


在较旧的浏览器上,可以使用和。你也可以:

import'abortcontroller polyfill/dist/abortcontroller polyfill only'
从“whatwg fetch”导入{fetch}
//如果本机浏览器实现支持中止,请使用本机浏览器实现
const abortableFetch=('signal'在新请求('')中)?window.fetch:fetch

//安装程序中止控制器
const controller=new AbortController();
//传来取回的信号
常数信号=控制器信号;
//照常取
获取(url,{signal})。然后(响应=>{
...
}).catch(e=>{
//如果你愿意的话,请点击中止
如果(e.name=='abortorror'){
...
}
});
//当你想中止时
controller.abort();
适用于edge 16(2017-10-17)、firefox 57(2017-11-14)、桌面safari 11.1(2018-03-29)、ios safari 11.4(2018-03-29)、chrome 67(2018-05-29)和更高版本


在较旧的浏览器上,可以使用和。你也可以:

import'abortcontroller polyfill/dist/abortcontroller polyfill only'
从“whatwg fetch”导入{fetch}
//如果本机浏览器实现支持中止,请使用本机浏览器实现
const abortableFetch=('signal'在新请求('')中)?window.fetch:fetch
TL/DR: 自2017年9月20日起,
fetch
现在支持
信号
参数,但不支持 目前所有浏览器似乎都支持这一点

2020更新:大多数主要浏览器(Edge、Firefox、Chrome、Safari、Opera和其他一些浏览器)已成为互联网的一部分。(截至2020年3月5日)

不过,我们很快就会看到这一变化,因此您应该能够使用
AbortController
s
AbortSignal
取消请求

长版本 如何: 其工作方式如下:

步骤1:创建一个
中止控制器
(目前我刚刚使用)

const controller=new AbortController()

步骤2:您会得到如下
中止控制器的信号:

const signal=controller.signal

步骤3:传递
信号
进行如下提取:

fetch(urlToFetch, {
    method: 'get',
    signal: signal, // <------ This is our AbortSignal
})
TL/DR: 自2017年9月20日起,
fetch
现在支持
信号
参数,但不支持 目前所有浏览器似乎都支持这一点

2020更新:大多数主要浏览器(Edge、Firefox、Chrome、Safari、Opera和其他一些浏览器)已成为互联网的一部分。(截至2020年3月5日)

不过,我们很快就会看到这一变化,因此您应该能够使用
AbortController
s
AbortSignal
取消请求

长版本 如何: 其工作方式如下:

步骤1:创建一个
中止控制器
(目前我刚刚使用)

const controller=new AbortController()

步骤2:您会得到如下
中止控制器的信号:

const signal=controller.signal

步骤3:传递
信号
进行如下提取:

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

从2018年2月起,
fetch()
可以在Chrome上用下面的代码取消(读取以启用Firefox支持)。要拾取
catch()
不会抛出错误,这是一个临时解决方案,直到完全采用
AbortController


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();
        })
      }
    }
  }
}

从2018年2月起,
fetch()
可以在Chrome上用下面的代码取消(读取以启用Firefox支持)。要拾取
catch()
不会抛出错误,这是一个临时解决方案,直到完全采用
AbortController


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();
        })
      }
    }
  }
}
让我们来填充:

if(!AbortController){
  class AbortController {
    constructor() {
      this.aborted = false;
      this.signal = this.signal.bind(this);
    }
    signal(abortFn, scope) {
      if (this.aborted) {
        abortFn.apply(scope, { name: 'AbortError' });
        this.aborted = false;
      } else {
        this.abortFn = abortFn.bind(scope);
      }
    }
    abort() {
      if (this.abortFn) {
        this.abortFn({ reason: 'canceled' });
        this.aborted = false;
      } else {
        this.aborted = true;
      }
    }
  }

  const originalFetch = window.fetch;

  const customFetch = (url, options) => {
    const { signal } = options || {};

    return new Promise((resolve, reject) => {
      if (signal) {
        signal(reject, this);
      }
      originalFetch(url, options)
        .then(resolve)
        .catch(reject);
    });
  };

  window.fetch = customFetch;
}
请记住,代码没有经过测试!如果你已经测试过了,但有些东西不起作用,请告诉我。它可能会警告您试图覆盖JavaScript官方库中的“fetch”函数。

让我们来填充:

if(!AbortController){
  class AbortController {
    constructor() {
      this.aborted = false;
      this.signal = this.signal.bind(this);
    }
    signal(abortFn, scope) {
      if (this.aborted) {
        abortFn.apply(scope, { name: 'AbortError' });
        this.aborted = false;
      } else {
        this.abortFn = abortFn.bind(scope);
      }
    }
    abort() {
      if (this.abortFn) {
        this.abortFn({ reason: 'canceled' });
        this.aborted = false;
      } else {
        this.aborted = true;
      }
    }
  }

  const originalFetch = window.fetch;

  const customFetch = (url, options) => {
    const { signal } = options || {};

    return new Promise((resolve, reject) => {
      if (signal) {
        signal(reject, this);
      }
      originalFetch(url, options)
        .then(resolve)
        .catch(reject);
    });
  };

  window.fetch = customFetch;
}

请记住,代码没有经过测试!如果你已经测试过了,但有些东西不起作用,请告诉我。它可能会警告您试图覆盖JavaScript官方库中的“fetch”函数。

这适用于浏览器和nodejs


这适用于浏览器和节点

简单类型脚本化版本(提取被中止):

简单类型脚本化版本(提取被中止):


这个答案是正确的,应该投票表决。但是我对代码片段进行了一些编辑,因为它实际上在Firefox 57+中不起作用-垫片似乎导致它失败(“Err:TypeError:'signal'RequestInit的成员没有实现接口AbortSignal”)。而且它的证书似乎存在一些问题(“此服务器无法证明它是slowwly.robertomurray.co.uk;其安全证书来自*.herokuapp.com。”),因此我将其更改为仅使用(纯http)。但现在它在其他浏览器(如Chrome)上不工作,因为
中止控制