mo / abortcontroller-polyfill Goto Github PK
View Code? Open in Web Editor NEWPolyfill for the AbortController DOM API and abortable fetch (stub that calls catch, doesn't actually abort request).
License: MIT License
Polyfill for the AbortController DOM API and abortable fetch (stub that calls catch, doesn't actually abort request).
License: MIT License
While working on JakeChampion/fetch#592 and bringing this in to have a full-featured polyfill for testing, I noticed it doesn't work inside a web worker as it uses the dom
to create an EventTarget
. Would you be willing to rework the Emitter
class to support that?
When I try to bundle this polyfill in my application I get the following error:
Error: Couldn't find preset "latest" relative to directory ".../node_modules/abortcontroller-polyfill"
Babel preset latest
is deprecated and this project references babel-preset-env
No error occurs if I change it to "env"
or remove the babel presets entry altogether.
Can the babel presets entry in package.json
be changed to "env"
or else removed (due to use of the .babelrc
file)?
"babel": {
"presets": [
"latest" <-- change to "env"
]
},
thanks for the suggestion @youennf
maybe something like this?
if (typeof(Request) == "function" && Request.prototype.hasOwnProperty("signal")) { ... }
If the first argument to fetch
is a Request object, then the polyfill should try and resolve the signal from there.
That is, in this line it is checked whether the Request
object has the signal
property, but in this line it is only checked whether the second argument has the property, and not the first if that is a Request
object.
See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout
The static AbortSignal.timeout() method returns an AbortSignal that will automatically abort after a specified time.
i use this library.
but ie is not working.
is not support ie??
First of all, this is Safari's fault.
Safari 12.0.1
supports AbortController
, so the polyfill is not applied, but it doesn't do anything.
Here's a really small example I made, with a delay on the request, just in case:
import 'whatwg-fetch';
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch';
const abortController = new AbortController();
const req = fetch(
'https://jsonplaceholder.typicode.com/todos/1',
{ signal: abortController.signal }
)
.then((response) => new Promise((resolve) => {
setTimeout(() => { resolve(response); }, 1000);
}));
abortController.abort();
req
.then((response) => response.json())
.then((response) => console.log(response))
.catch((error) => { console.error(error); });
If you try this out on Chrome, it works like a charm, but on Safari doesn't.
Just to test if it was a Safari issue, I went to your package and removed the following check (to apply the polyfill even if there was support):
if (self.AbortController) {
return;
}
And it worked.
Finally, the reason I'm opening the issue is to see if...
I'm using your polyfill with whatwg-fetch.
I have something like this:
_this.fetchController.abort();
fetch(this.props.dataSource, {
signal: _this.fetchController.signal,
method: "POST",
body: JSON.stringify({
strict,
page,
....
I would like to ensure that there's only one fetch request going out to that specific resource at any one point, so each user interaction would abort a running request and start a new one.
However what happens in practice is that AbortController will abort the running request and also the new one that would start right after it.
I've got the following snippet of code:
const controller = new AbortController();
controller.signal.addEventListener('abort', () => console.log('aborting'));
(function () {
controller.abort();
console.log('done aborting');
})();
When I run this in Chrome, I get the following output:
aborting
done aborting
But when I run this using this polyfill, I get the following:
done aborting
aborting
It looks like this is because the events handlers are debounced. If I were to use signal.onAbort = ...
it would behave the same as Chrome, but I'd rather use the addEventListener
handler as it avoids directly mutating signal
.
I get lots of odd issues with this package, and as soon as I used https://github.com/mysticatea/abort-controller they seemed to go away. Just wanted to share this.
Exception has occurred: ReferenceError
ReferenceError: DOMException is not defined
at _fetch (/node_modules/abortcontroller-polyfill/dist/cjs-ponyfill.js:400:9)
Object.keys(new AbortController().signal) is [] for the native AbortController but this is not the case for the polyfill
When an AbortController is used with more than one request and aborted, only one of the requests is successfully aborted.
Test case: https://github.com/tekwiz/node-fetch/blob/feature/abort-controller-tests/test/main.js#L890
Test run: https://github.com/tekwiz/node-fetch/runs/1674440695?check_suite_focus=true#step:7:256
I attempted backing off the abortcontroller-polyfill
package to 1.6.0, and the test still fails; however, backing off the abortcontroller-polyfill
package to 1.5.0 fixes the issue.
Because of the below prototype check a working implementation of AbortController in Pale Moon browser is overwritten with one that causes an exception.
function polyfillNeeded(self) {
if (self.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
console.log('__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill');
return true;
} // Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// so the below feature detection needs the !self.AbortController part.
// The Request.prototype check is also needed because Safari versions 11.1.2
// up to and including 12.1.x has a window.AbortController present but still
// does NOT correctly implement abortable fetch:
// https://bugs.webkit.org/show_bug.cgi?id=174980#c2
return typeof self.Request === 'function' && !self.Request.prototype.hasOwnProperty('signal') || !self.AbortController;
}
When using this polyfill any use of the signal in a fetch call will result in a 'signal' member of RequestInit does not implement interface AbortSignal.
exception.
To reproduce the issue you can use this snippet:
var controller = new AbortController();
var signal = controller.signal;
fetch(location.href, {signal});
setTimeout(function() { controller.abort(); }, 50);
After adding the polyfil to the top of the entry point in the webpack throws an error on initial load.
"webpack": "^4.20.2",
"abortcontroller-polyfill": "^1.2.3",
Something along this:
const nativeProto = Request.prototype;
const NativeRequest = Request;
Request = function (input, init) {
let request = new NativeRequest(input, init);
if (init && init.signal) {
request.signal = init.signal;
}
return request;
}
Request.prototype = nativeProto;
Simple sample code:
// Server implmentation
import express from 'express';
const app = express();
app.use((req, res, next) => {
req.on('close', () => console.log('CLOSED'));
next();
});
app.get('*', (req, res) => setTimeout(() => res.send('Ok'), 5000));
app.listen(808, () => console.log('http://localhost:808'));
// Client code
let execute = async (fetch, AbortController) => {
const ac = new AbortController();
const rP = fetch('http://localhost:808', { signal: ac.signal });
setTimeout(() => ac.abort(),1000);
try {
console.log(await rP);
} catch (ex) {
console.log(ex.name);
}
};
When I run client code on browser:
execute(fetch, AbortController)
On server console I see the 'CLOSED' on client 'AbortErrror'.
Now when I try to run client on node :
import { AbortController, AbortSignal, abortableFetch } from 'abortcontroller-polyfill/dist/cjs-ponyfill';
import nodeFetch from 'node-fetch';
const { fetch } = abortableFetch(nodeFetch);
execute(fetch, AbortController);
On client I see 'AbortErrror', but there is no any log on Server .
For compassion, if I use https://www.npmjs.com/package/abort-controller :
import AbortController from 'abort-controller';
import fetch from 'node-fetch';
execute(fetch, AbortController);
I have same result as on browser.
I lost half a day to finally find that 'abortcontroller-polyfill' is not support real request cancellation (I was looking for problem in my code :().
Maybe this is problem with this particular versions, I do not know.
Please fix that or at least add information about such limitation in documentation.
Best regards.
I've used create-react-app
(which means Webpack under the hook!), and when I tried to play with this polyfill I had the following error:
Line 77: 'AbortController' is not defined no-undef
I added some console.log
in the abortcontroller script and saw nothing...
The upcoming new version of Safari will ship the native Abordable Fetch controller. The latest preview release 74 released recently has fixed the missing API:
https://developer.apple.com/safari/technology-preview/release-notes/
The reported issue #23 and #24 pull requests weter supposed to fix the broken API, but in the recent version of Safari Preview, the polyfill brakes the browser runtime.
Repro steps:
pnpm create next-app --ts
middleware.ts
with import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
pnpm i
and pnpm dev
Expected result:
App runs
Actual result:
TypeError: Cannot redefine property: AbortController
It detects the environment as needing a polyfill via this line. The fetch
property is missing, but it is unable to redefine the AbortController` property on the global object.
https://github.com/David-Rickard/abortcontroller-polyfill-nextjs-repro
There is a modern API method to throw abort reason, if operation was aborted: AbortSignal.throwIfAborted()
.
WhatWG specification: https://dom.spec.whatwg.org/#ref-for-dom-abortsignal-throwifaborted
Example implementation: nodejs/node#40951
If would be great if this polyfill will support it.
I'm using a fetch request to get blob data from the server in the form of PNGs. If the request goes beyond a specific timeout that I've set, I am calling abort on the request (as per your instructions). The abort seems to run tough without errors, but looking at the network tab, the fetches still report "pending", eventually to return with 200 status. Is there something I'm missing?
Using updated Chrome on Linux Mint.
Hi, we are interested in using this module in node-fetch (basically a fetch()
for Node.js), but it seems like this module does not yet support Node.js. Would you folks be opposed to a Node.js version using something like event-target-shim or Node.js' internal EventEmitter
class that makes this package Node.js-compatible? Thanks!
I'm trying to use this in a Typescript project, but am having to in an odd way because this library doesn't have type module definitions. Any plans to add this? I'm happy to spin up a PR if it's helpful.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.