How to polyfill JavaScript fetch function for Internet Explorer
Adrian Bece
Posted on September 7, 2020
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.
Posted on September 7, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
October 17, 2024