1 | # AbortController polyfill for abortable fetch()
|
2 |
|
3 | [![npm version](https://badge.fury.io/js/abortcontroller-polyfill.svg)](https://badge.fury.io/js/abortcontroller-polyfill)
|
4 |
|
5 | Minimal stubs so that the AbortController DOM API for terminating ```fetch()``` requests can be used
|
6 | in browsers that doesn't yet implement it. This "polyfill" doesn't actually close the connection
|
7 | when the request is aborted, but it will call ```.catch()``` with ```err.name == 'AbortError'```
|
8 | instead of ```.then()```.
|
9 |
|
10 | ```js
|
11 | const controller = new AbortController();
|
12 | const signal = controller.signal;
|
13 | fetch('/some/url', {signal})
|
14 | .then(res => res.json())
|
15 | .then(data => {
|
16 | // do something with "data"
|
17 | }).catch(err => {
|
18 | if (err.name == 'AbortError') {
|
19 | return;
|
20 | }
|
21 | });
|
22 | // controller.abort(); // can be called at any time
|
23 | ```
|
24 |
|
25 | You can read about the [AbortController](https://dom.spec.whatwg.org/#aborting-ongoing-activities) API in the DOM specification.
|
26 |
|
27 | # How to use
|
28 |
|
29 | ```shell
|
30 | $ npm install --save abortcontroller-polyfill
|
31 | ```
|
32 |
|
33 | If you're using webpack or similar, you then import it early in your client entrypoint .js file using
|
34 |
|
35 | ```js
|
36 | import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
|
37 | // or:
|
38 | require('abortcontroller-polyfill/dist/polyfill-patch-fetch')
|
39 | ```
|
40 |
|
41 | ## Using it on browsers without fetch
|
42 |
|
43 | If you need to support browsers where fetch is not available at all (for example
|
44 | Internet Explorer 11), you first need to install a fetch polyfill and then import
|
45 | the ```abortcontroller-polyfill``` afterwards.
|
46 |
|
47 | The [unfetch](https://www.npmjs.com/package/unfetch) npm package offers a minimal ```fetch()```
|
48 | implementation (though it does not offer for example a ```Request``` class). If you need a polyfill that
|
49 | implements the full Fetch specification, use the
|
50 | [whatwg-fetch](https://www.npmjs.com/package/whatwg-fetch) npm package instead. Typically you will
|
51 | also need to load a polyfill that implements ES6 promises, for example
|
52 | [promise-polyfill](https://www.npmjs.com/package/promise-polyfill), and of course you need to avoid
|
53 | ES6 arrow functions and template literals.
|
54 |
|
55 | Example projects showing abortable fetch setup so that it works even in Internet Explorer 11, using
|
56 | both unfetch and GitHub fetch, is available
|
57 | [here](https://github.com/mo/abortcontroller-polyfill-examples).
|
58 |
|
59 | ## Using it along with 'create-react-app'
|
60 |
|
61 | create-react-app enforces the no-undef eslint rule at compile time so if your
|
62 | version of eslint does not list ```AbortController``` etc as a known global for
|
63 | the ```browser``` environment, then you might run into an compile error like:
|
64 |
|
65 | ```
|
66 | 'AbortController' is not defined no-undef
|
67 | ```
|
68 |
|
69 | This can be worked around by (temporarily, details [here](https://github.com/mo/abortcontroller-polyfill/issues/10)) adding a declaration like:
|
70 |
|
71 | ```js
|
72 | const AbortController = window.AbortController;
|
73 | ```
|
74 |
|
75 | ## Using the AbortController/AbortSignal without patching fetch
|
76 |
|
77 | If you just want to polyfill AbortController/AbortSignal without patching fetch
|
78 | you can use:
|
79 |
|
80 | ```js
|
81 | import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
|
82 | ```
|
83 |
|
84 | # Using it on Node.js
|
85 |
|
86 | You can either import it as a [ponyfill](https://ponyfill.com/) without modifying globals:
|
87 |
|
88 | ```js
|
89 | const { AbortController, abortableFetch } = require('abortcontroller-polyfill/dist/cjs-ponyfill');
|
90 | const { fetch } = abortableFetch(require('node-fetch'));
|
91 | // or
|
92 | // import AbortController, { abortableFetch } from 'abortcontroller-polyfill/dist/cjs-ponyfill';
|
93 | // import _fetch from 'node-fetch';
|
94 | // const { fetch } = abortableFetch(_fetch);
|
95 | ```
|
96 | or if you're lazy
|
97 | ```js
|
98 | global.fetch = require('node-fetch');
|
99 | require('abortcontroller-polyfill/dist/polyfill-patch-fetch');
|
100 | ```
|
101 |
|
102 | If you also need a ```Request``` class with support for aborting you can do:
|
103 |
|
104 | ```js
|
105 | const { AbortController, abortableFetch } = require('abortcontroller-polyfill/dist/cjs-ponyfill');
|
106 | const _nodeFetch = require('node-fetch');
|
107 | const { fetch, Request } = abortableFetch({fetch: _nodeFetch, Request: _nodeFetch.Request});
|
108 |
|
109 | const controller = new AbortController();
|
110 | const signal = controller.signal;
|
111 | controller.abort();
|
112 | fetch(Request("http://api.github.com", {signal}))
|
113 | .then(r => r.json())
|
114 | .then(j => console.log(j))
|
115 | .catch(err => {
|
116 | if (err.name === 'AbortError') {
|
117 | console.log('aborted');
|
118 | }
|
119 | })
|
120 | ```
|
121 |
|
122 | See also Node.js examples [here](https://github.com/mo/abortcontroller-polyfill-examples/tree/master/node)
|
123 |
|
124 | # Contributors
|
125 | * [Martin Olsson](https://github.com/mo)
|
126 | * [Jimmy Wärting](https://github.com/jimmywarting)
|
127 | * [silverwind](https://github.com/silverwind)
|
128 | * [Rasmus Jacobsen](https://github.com/rmja)
|
129 | * [João Vieira](https://github.com/joaovieira)
|
130 | * [Cyril Auburtin](https://github.com/caub)
|
131 |
|
132 | # License
|
133 |
|
134 | MIT
|