- From: Jan Jaap <notifications@github.com>
- Date: Sun, 16 Jul 2017 06:04:22 -0700
- To: whatwg/fetch <fetch@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/fetch/issues/447/315608008@github.com>
The following solution enables cancellation of Fetch requests in all browsers, including IE. It would also enable targeted cancellation of any other javascript execution (e.g. creating a blob with javascript code and abort any of that code execution on demand).
Firefox:

Chrome:

```javascript
var fetch = (function() {
var fetchcount = 0;
// Create IE + others compatible event handler
var handlers = window.addEventListener ? ["addEventListener", "removeEventListener"] : ["attachEvent", "detachEvent"];
var watchEvent = handlers[0] == "attachEvent" ? "onmessage" : "message";
var watch = window[handlers[0]];
var unwatch = window[handlers[1]];
var cancelableFetch = function() {
var cancel; // cancel method
var fetchArgs = Array.prototype.slice.call(arguments);
var promise = new Promise(function(resolve, reject) {
var cancelled = false;
var fetchid = ++fetchcount;
var iframe = document.createElement('iframe');
iframe.id = iframe.name = 'fetch' + fetchid;
iframe.style = 'display:none;';
document.body.appendChild(iframe);
var d = (iframe.contentWindow || iframe.contentDocument);
if (d.document) {
d = d.document
}
var resolveFetch = function(e) {
if (e.data[0] === fetchid) {
resolve(e.data[1]);
unwatch(watchEvent, resolveFetch, false);
}
};
// Listen to message from child window
watch(watchEvent, resolveFetch, false);
d.open();
d.write('<script>fetch.apply(this,'+JSON.stringify(fetchArgs)+').then(function(response) { response.text().then(function(data) { parent.postMessage([' + fetchid + ',data],' + JSON.stringify(document.location.href) + '); }); });</script>');
d.close();
cancel = function() {
if (cancelled) {
return;
}
cancelled = true;
console.warn('Fetch aborted');
try {
if (typeof(window.frames['fetch' + fetchid].stop) === 'undefined') {
//Internet Explorer code
window.frames['fetch' + fetchid].document.execCommand('Stop');
} else {
//Other browsers
window.frames['fetch' + fetchid].stop();
}
} catch (e) {}
document.body.removeChild(iframe);
};
});
return {
then: function(resolve) {
return promise.then(resolve);
},
cancel: cancel
};
};
return cancelableFetch;
})();
// reqular fetch request
var request = fetch('https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js');
// regular processing of result
request.then(function(body) {
console.log("Fetch complete:", (typeof body === 'string') ? body.length : body);
}).catch(function(err) {
console.log(err.message);
});
// cancel request after +/- 170ms (fine tune to test cancellation in Firefox)
setTimeout(function() {
request.cancel();
}, 170);
```
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/issues/447#issuecomment-315608008
Received on Sunday, 16 July 2017 13:04:49 UTC