I love using fetch
API for my personal projects. When using Babel and working on React project, ES6 syntax gets transpiled and polyfilled automatically on build time. But what we need to do when we want to use fetch
API on a simple project that doesn't use Babel or Webpack? We need to manually polyfill it, and make sure the additional polyfills do not affect website performance.
A polyfill is a piece of code (usually JavaScript on the Web) used to provide modern functionality on older browsers that do not natively support it.
Why use "fetch"?
Before fetch
API was introduced, creating HTTP requests using XMLHttpRequest
was complicated and the syntax was not clean and straightforward.
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://path/to/api.endpoint");
xhr.send();
xhr.onload = function() {
// Handle response
};
xhr.onprogress = function(event) {
// Handle progress
};
xhr.onerror = function() {
// Handle error
};
Yeah, that is a lot of boilerplate code separated into multiple class methods and event handlers.
There were also some JavaScript plugins and jQuery (ajax) functions that act as a wrapper around XMLHttpRequest
to simplify it and improve the syntax, but there were no official API improvements until ES6 fetch
API.
Fetch API
Fetch API allows us to make HTTP requests using much simpler and straightforward JavaScript syntax to send and receive data, and handle any event using JavaScript promises.
fetch("https://path/to/api.endpoint")
.then(handleResponse)
.catch(handleFallback);
Looks simple enough, right?
This improved syntax made the whole functionality more accessible and developer-friendly. Although fetch
browser support sits at comfortable 95%, we can easily polyfill it so even more browsers support it.
Polyfilling fetch for Internet Explorer
We don't want to just add the polyfill to project so it loads for all browsers (including those that support fetch natively). Let's load the polyfill dynamically so extra JavaScript is loaded only if it's required.
For fetch
to work on Internet Explorer, we need to add two polyfills:
- Promise polyfill - remember,
fetch
uses promises - Fetch polyfill
// Detect if user is on IE browser
var isIE = !!window.MSInputMethodContext && !!document.documentMode;
if (isIE) {
// Create Promise polyfill script tag
var promiseScript = document.createElement("script");
promiseScript.type = "text/javascript";
promiseScript.src =
"https://cdn.jsdelivr.net/npm/promise-polyfill@8.1.3/dist/polyfill.min.js";
// Create Fetch polyfill script tag
var fetchScript = document.createElement("script");
fetchScript.type = "text/javascript";
fetchScript.src =
"https://cdn.jsdelivr.net/npm/whatwg-fetch@3.4.0/dist/fetch.umd.min.js";
// Add polyfills to head element
document.head.appendChild(promiseScript);
document.head.appendChild(fetchScript);
// Wait for the polyfills to load and run the function.
// We could have done this differently,
// but I've found it to work well for my use-cases
setTimeout(function () {
window
.fetch("https://path/to/api.endpoint")
.then(handleResponse)
.catch(handleErrors);
}, 1000);
} else {
// If fetch is supported, just run the fetch function
fetch("https://path/to/api.endpoint")
.then(handleResponse)
.catch(handleErrors);
}
And that is it. If user is using Internet Explorer, fetch
function will be added to global window
object and be used as window.fetch()
.
Conclusion
I've used this method to load articles from DEV on my personal website using fetch
and it works as expected. This was really simple to implement and I was happy with the final results. I was also happy that I'm not loading the polyfills if they're not needed.
Note: Also feel free to leave a comment on how I can improve my code to replace setTimeout
function and make sure that this part of the code waits until polyfill becomes available.
These articles are fueled by coffee. So if you enjoy my work and found it useful, consider buying me a coffee! I would really appreciate it.
Thank you for taking the time to read this post. If you've found this useful, please give it a ❤️ or 🦄, share and comment.
Top comments (6)
Thanks for posting. I found this helpful. However, instead of testing for IE, it seems more robust to mimic/duplicate the test that the fetch polyfill, itself, performs, like so:
github.com/github/fetch/blob/maste...
Mike....
What about not using a polyfill? It's 2020. How many visitors would really be bothered? People using ie9 should be used to getting errors and exploded layouts anyway.
I still want to support IE11 as it comes pre-installed on Windows machines alongside Edge by default. It's okay to support it in this way since the polyfills don't affect performance on supported browsers.
I don't see any issue here. It's always okay to support older browsers and ensure good UX for them if it's viable and if it's not at performance cost, no matter which year it is.
Sure it's a hard sell but my point is that all that backward compatibility is holding back the platform as a whole. And Edge should have replaced IE.
This is true, however alot of hospitals and other clinicalsites around the world is still using windows xp or if updated and upgraded - windows 7. So if you develop anything for these particular users, this is pretty helpful if you don't want to fiddle around with ajax syntax.
That's easy to say, but a lot of enterprise environments still use IE on their workstations. They will expect their site to perform as normal.