164 lines
6.2 KiB
Markdown
164 lines
6.2 KiB
Markdown
|
# AbortController polyfill for abortable fetch()
|
||
|
|
||
|
[![npm version](https://badge.fury.io/js/abortcontroller-polyfill.svg)](https://badge.fury.io/js/abortcontroller-polyfill)
|
||
|
|
||
|
Minimal stubs so that the AbortController DOM API for terminating ```fetch()``` requests can be used
|
||
|
in browsers that doesn't yet implement it. This "polyfill" doesn't actually close the connection
|
||
|
when the request is aborted, but it will call ```.catch()``` with ```err.name == 'AbortError'```
|
||
|
instead of ```.then()```.
|
||
|
|
||
|
```js
|
||
|
const controller = new AbortController();
|
||
|
const signal = controller.signal;
|
||
|
fetch('/some/url', {signal})
|
||
|
.then(res => res.json())
|
||
|
.then(data => {
|
||
|
// do something with "data"
|
||
|
}).catch(err => {
|
||
|
if (err.name == 'AbortError') {
|
||
|
return;
|
||
|
}
|
||
|
});
|
||
|
// controller.abort(); // can be called at any time
|
||
|
```
|
||
|
|
||
|
You can read about the [AbortController](https://dom.spec.whatwg.org/#aborting-ongoing-activities) API in the DOM specification.
|
||
|
|
||
|
# How to use
|
||
|
|
||
|
```shell
|
||
|
$ npm install --save abortcontroller-polyfill
|
||
|
```
|
||
|
|
||
|
If you're using webpack or similar, you then import it early in your client entrypoint .js file using
|
||
|
|
||
|
```js
|
||
|
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
|
||
|
// or:
|
||
|
require('abortcontroller-polyfill/dist/polyfill-patch-fetch')
|
||
|
```
|
||
|
|
||
|
## Using it on browsers without fetch
|
||
|
|
||
|
If you need to support browsers where fetch is not available at all (for example
|
||
|
Internet Explorer 11), you first need to install a fetch polyfill and then
|
||
|
import the ```abortcontroller-polyfill``` afterwards.
|
||
|
|
||
|
The [unfetch](https://www.npmjs.com/package/unfetch) npm package offers a minimal ```fetch()```
|
||
|
implementation (though it does not offer for example a ```Request``` class). If you need a polyfill that
|
||
|
implements the full Fetch specification, use the
|
||
|
[whatwg-fetch](https://www.npmjs.com/package/whatwg-fetch) npm package instead. Typically you will
|
||
|
also need to load a polyfill that implements ES6 promises, for example
|
||
|
[promise-polyfill](https://www.npmjs.com/package/promise-polyfill), and of course you need to avoid
|
||
|
ES6 arrow functions and template literals.
|
||
|
|
||
|
Example projects showing abortable fetch setup so that it works even in Internet Explorer 11, using
|
||
|
both unfetch and GitHub fetch, is available
|
||
|
[here](https://github.com/mo/abortcontroller-polyfill-examples).
|
||
|
|
||
|
## Using it along with 'create-react-app'
|
||
|
|
||
|
create-react-app enforces the no-undef eslint rule at compile time so if your
|
||
|
version of eslint does not list ```AbortController``` etc as a known global for
|
||
|
the ```browser``` environment, then you might run into an compile error like:
|
||
|
|
||
|
```
|
||
|
'AbortController' is not defined no-undef
|
||
|
```
|
||
|
|
||
|
This can be worked around by (temporarily, details [here](https://github.com/mo/abortcontroller-polyfill/issues/10)) adding a declaration like:
|
||
|
|
||
|
```js
|
||
|
const AbortController = window.AbortController;
|
||
|
```
|
||
|
|
||
|
## Using the AbortController/AbortSignal without patching fetch
|
||
|
|
||
|
If you just want to polyfill AbortController/AbortSignal without patching fetch
|
||
|
you can use:
|
||
|
|
||
|
```js
|
||
|
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
|
||
|
```
|
||
|
|
||
|
# Using it on Node.js
|
||
|
|
||
|
You can either import it as a [ponyfill](https://ponyfill.com/) without modifying globals:
|
||
|
|
||
|
```js
|
||
|
const { AbortController, abortableFetch } = require('abortcontroller-polyfill/dist/cjs-ponyfill');
|
||
|
const { fetch } = abortableFetch(require('node-fetch'));
|
||
|
// or
|
||
|
// import { AbortController, abortableFetch } from 'abortcontroller-polyfill/dist/cjs-ponyfill';
|
||
|
// import _fetch from 'node-fetch';
|
||
|
// const { fetch } = abortableFetch(_fetch);
|
||
|
```
|
||
|
or if you're lazy
|
||
|
```js
|
||
|
global.fetch = require('node-fetch');
|
||
|
require('abortcontroller-polyfill/dist/polyfill-patch-fetch');
|
||
|
```
|
||
|
|
||
|
If you also need a ```Request``` class with support for aborting you can do:
|
||
|
|
||
|
```js
|
||
|
const { AbortController, abortableFetch } = require('abortcontroller-polyfill/dist/cjs-ponyfill');
|
||
|
const _nodeFetch = require('node-fetch');
|
||
|
const { fetch, Request } = abortableFetch({fetch: _nodeFetch, Request: _nodeFetch.Request});
|
||
|
|
||
|
const controller = new AbortController();
|
||
|
const signal = controller.signal;
|
||
|
controller.abort();
|
||
|
fetch(Request("http://api.github.com", {signal}))
|
||
|
.then(r => r.json())
|
||
|
.then(j => console.log(j))
|
||
|
.catch(err => {
|
||
|
if (err.name === 'AbortError') {
|
||
|
console.log('aborted');
|
||
|
}
|
||
|
})
|
||
|
```
|
||
|
|
||
|
See also Node.js examples [here](https://github.com/mo/abortcontroller-polyfill-examples/tree/master/node)
|
||
|
|
||
|
# Using it on Internet Explorer 11 (MSIE11)
|
||
|
|
||
|
The ```abortcontroller-polyfill``` works on Internet Explorer 11. However, to use it you must first
|
||
|
install separate polyfills for promises and for ```fetch()```. For the promise polyfill, you can
|
||
|
use the ```promise-polyfill``` package from npm, and for ```fetch()``` you can use either the ```whatwg-fetch``` npm package (complete fetch implementation) or the ```unfetch``` npm package (not a complete polyfill but it's only 500 bytes large and covers a lot of the basic use cases).
|
||
|
|
||
|
If you choose ```unfetch```, the imports should be done in this order for example:
|
||
|
|
||
|
```js
|
||
|
import 'promise-polyfill/src/polyfill';
|
||
|
import 'unfetch/polyfill';
|
||
|
import 'abortcontroller-polyfill';
|
||
|
```
|
||
|
|
||
|
See example code [here](https://github.com/mo/abortcontroller-polyfill-examples/tree/master/create-react-app-msie11).
|
||
|
|
||
|
# Using it on Internet Explorer 8 (MSIE8)
|
||
|
|
||
|
The ```abortcontroller-polyfill``` works on Internet Explorer 8. However, since ```github-fetch```
|
||
|
only supports IE 10+ you need to use the ```fetch-ie8``` npm package instead and also note that IE 8 only
|
||
|
implements ES 3 so you need to use the ```es5-shim``` package (or similar). Finally, just like with
|
||
|
IE 11 you also need to polyfill promises. One caveat is that CORS requests will not work out of the box on IE 8.
|
||
|
|
||
|
Here is a basic example of [abortable fetch running in IE 8](https://github.com/mo/abortcontroller-polyfill-examples/tree/master/plain-javascript-fetch-ie8).
|
||
|
|
||
|
# Contributors
|
||
|
* [Martin Olsson](https://github.com/mo)
|
||
|
* [Jimmy Wärting](https://github.com/jimmywarting)
|
||
|
* [silverwind](https://github.com/silverwind)
|
||
|
* [Rasmus Jacobsen](https://github.com/rmja)
|
||
|
* [João Vieira](https://github.com/joaovieira)
|
||
|
* [Cyril Auburtin](https://github.com/caub)
|
||
|
* [Leonardo Apiwan](https://github.com/homer0)
|
||
|
* [Jake Champion](https://github.com/JakeChampion)
|
||
|
* [Sai Srinivasan](https://github.com/SairamSrinivasan)
|
||
|
* [Ambar Lee](https://github.com/ambar)
|
||
|
|
||
|
# License
|
||
|
|
||
|
MIT
|