- 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: ![image](https://user-images.githubusercontent.com/8843669/28247756-61995584-6a37-11e7-8560-492e5b47ca89.png) Chrome: ![image](https://user-images.githubusercontent.com/8843669/28247758-75e6a474-6a37-11e7-9a68-27cf28e36e57.png) ```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