Testing

Fetch API: Browser Support, Features, Limitations

Fetch API supports Chrome 42+, Edge 14+, Firefox 39+, Safari 10.1+ on macOS, and Safari 10.3+ on iOS. See full Fetch API browser support.

Author

Prince Dewani

May 1, 2026

The Fetch API is a WHATWG JavaScript interface for making HTTP network requests with a Promise-based fetch() method. It supports Chrome 42+, Edge 14+, Firefox 39+, Safari 10.1+ on macOS, Safari 10.3+ on iOS, Opera 29+, Samsung Internet 4+, and Opera Mobile 80+, while Internet Explorer 5.5 through 11 never added support.

This guide covers what the Fetch API is, the browsers that support it, the key features, how to check browser support, and the known issues.

What is the Fetch API?

The Fetch API is a JavaScript interface defined by the WHATWG Fetch Standard for making HTTP network requests from the browser. It exposes a global fetch() method that returns a Promise resolving to a Response object, plus the Headers, Request, Response, and Body interfaces for shaping payloads.

Which browsers does the Fetch API support?

The Fetch API ships by default in every current Chromium browser, Firefox, and Safari. Internet Explorer never added support, and a few legacy mobile builds did not ship it either.

Loading browser compatibility data...

Fetch API compatibility in Chrome

Chrome supports the Fetch API from Chrome 42 on Windows, macOS, Linux, ChromeOS, and Android. Chrome 40 to 41 had partial support behind the Experimental Web Platform features flag at chrome://flags; Chrome 4 to 39 did not support fetch() at all and threw a ReferenceError on window.fetch.

Fetch API compatibility in Edge

Microsoft Edge supports the Fetch API from Edge 14 on Windows. Edge 12 to 13 did not expose fetch(). Chromium-based Edge inherits Chrome 79+ behavior on Windows, macOS, Linux, and Android, so every modern Edge build ships the Fetch API by default with the same Headers, Request, and Response interfaces as Chrome.

Fetch API compatibility in Firefox

Firefox supports the Fetch API from Firefox 39 on Windows, macOS, Linux, and Android. Firefox 34 to 38 had the API disabled by default behind the dom.fetch.enabled preference in about:config; Firefox 2 to 33 did not support it. Firefox for Android picked up fetch() in the same release cycle as desktop Firefox 39.

Fetch API compatibility in Safari

Safari supports the Fetch API from Safari 10.1 on macOS Sierra and from Safari 10.3 on iOS 10.3. Safari 3.1 to 10 on macOS and Safari 3.2 to 10.2 on iOS did not support fetch() and require the whatwg-fetch polyfill on those legacy versions. Safari was the last major browser to ship the API natively, so cross-browser code shipped before Safari 10.1 must feature-detect.

Fetch API compatibility in Opera

Opera supports the Fetch API from Opera 29 on Windows, macOS, and Linux through the Chromium 42 base. Opera 27 to 28 had partial support behind the same Experimental Web Platform features flag as Chrome, and Opera 9 to 26 did not support the API. Opera Mobile picked up the Fetch API in Opera Mobile 80 on Android.

Fetch API compatibility in Samsung Internet

Samsung Internet supports the Fetch API from Samsung Internet 4.0 on Galaxy phones and tablets running Android. Samsung Internet 1.0 to 3.0 did not support fetch(). Newer Samsung Internet builds align with the underlying Chromium release, so the Fetch API extends to every modern Galaxy device with the same defaults as Chrome for Android.

Fetch API compatibility in Android Browser

The legacy stock Android Browser, frozen at version 4.4 before Chrome for Android took over, did not support the Fetch API. Modern Android Browser builds (147) ship fetch() by default. On any current Android phone, use Chrome for Android, Samsung Internet, or another Chromium-based browser to call the Fetch API without a polyfill.

Fetch API compatibility in Internet Explorer

Internet Explorer never added Fetch API support. IE 5.5 through IE 11 do not expose window.fetch and require the whatwg-fetch polyfill plus a Promise polyfill before any fetch call. Microsoft has retired Internet Explorer, so use Edge, Chrome, or Firefox for native fetch(), or transpile and polyfill if you must run on IE 11.

Note

Note: Fetch API support varies across older Safari, mobile browsers, and Internet Explorer. Test it on real browsers and OS with TestMu AI. Try TestMu AI free!

What are the key features of the Fetch API?

The Fetch API replaces XMLHttpRequest with a small, Promise-friendly surface that lines up with service workers, streams, and modern security defaults. The features below are the ones you reach for most often in production code.

  • Promise-based fetch(): The global fetch(input, init) call returns a Promise that resolves to a Response object as soon as the server sends headers, even on a 404 or 500. Use response.ok or response.status to branch on success.
  • Request and Response objects: Both interfaces are first-class values you can clone, pass to a service worker, or store in a Cache. A Request carries the URL, method, headers, body, and credentials policy; a Response wraps the status, headers, and body.
  • Body methods: response.text(), response.json(), response.blob(), response.arrayBuffer(), and response.formData() each return a Promise. Each method drains the body once, so call clone() first if you need to read it twice.
  • Headers interface: new Headers() exposes get, set, append, has, delete, and an iterable entries() view. The Fetch spec auto-lowercases header names, so the Headers object normalizes the case differences XMLHttpRequest left to the caller.
  • Request cancellation with AbortController: Pass controller.signal to fetch through the signal option and call controller.abort() to cancel an in-flight request. AbortController works in Chrome 66+, Edge 16+, Firefox 57+, and Safari 11.1+.
  • Streaming responses: response.body is a ReadableStream, so you can consume bytes as they arrive without buffering the full payload. This is the basis for streamed JSON parsers, server-sent event polyfills, and progressive image decoders.
  • Credentials and CORS modes: The init object accepts credentials ("omit", "same-origin", "include") and mode ("cors", "no-cors", "same-origin", "navigate"). The defaults match the modern web: credentials default to same-origin, mode defaults to cors.

How do you check if a browser supports the Fetch API?

Run a one-line feature-detection check at the top of your script and load the whatwg-fetch polyfill on browsers that fail it. Five steps cover the full path from detection to verified output.

  • Open DevTools console: Load any page in the target browser, press F12 (or Cmd+Option+I on macOS), and switch to the Console tab.
  • Probe window.fetch: Type typeof window.fetch and press Enter. The console prints "function" on supported browsers and "undefined" on Internet Explorer or older Safari.
  • Check AbortController: Type typeof window.AbortController. A "function" result confirms the browser supports request cancellation, which lines up with Chrome 66+, Edge 16+, Firefox 57+, and Safari 11.1+.
  • Add the polyfill: If fetch is undefined, load whatwg-fetch with a script tag (or import "whatwg-fetch" in a bundler) and load a Promise polyfill before it for IE 11. The polyfill installs window.fetch with the same call signature.
  • Confirm with a real call: Paste the snippet below into the console on the same page. The handler logs "Fetch ready" with the response body when the API works, and a clear warning when it does not.
function isFetchSupported() {
    return typeof window !== "undefined"
        && typeof window.fetch === "function"
        && typeof window.Promise === "function";
}

if (isFetchSupported()) {
    fetch("/api/health", { credentials: "same-origin" })
        .then((response) => {
            if (!response.ok) {
                throw new Error("Bad status: " + response.status);
            }
            return response.json();
        })
        .then((data) => console.log("Fetch ready, server said:", data))
        .catch((error) => console.warn("Fetch error:", error.message));
} else {
    console.warn("Fetch API missing - load whatwg-fetch polyfill first");
}

If the console reports a CORS error instead of a network error, fetch is supported but the server is missing the Access-Control-Allow-Origin header. Switch the request to a same-origin URL to confirm the API itself.

...

What are the known issues with the Fetch API?

The Fetch API is stable, but a handful of behaviors surprise developers who came from XMLHttpRequest or jQuery.ajax. Most cross-browser bugs trace back to these gaps.

  • HTTP errors do not reject: A 404 or 500 response still resolves the Promise. Check response.ok inside the first .then and throw if the status is not in the 200 range, otherwise the catch handler never runs on real server failures.
  • Internet Explorer is unsupported: IE 5.5 through 11 do not expose window.fetch. Any bundle that calls fetch() without the whatwg-fetch polyfill throws ReferenceError on the first call and breaks the page.
  • No native timeout option: The Fetch API has no timeout setting. Wire AbortController to a setTimeout that calls controller.abort() if you need to cap the request, since long requests otherwise hang until the server closes the connection.
  • Limited upload progress: The Fetch API does not expose XHR-style upload.onprogress events. Use a ReadableStream request body and count bytes as you write to track upload progress, or fall back to XMLHttpRequest for large file uploads.
  • Streaming uploads are partial: Sending a ReadableStream as the request body works in Chrome 105+ over HTTP/2, but Firefox and Safari still buffer the full body before sending. Plan your wire protocol around the slowest target.
  • Credentials default surprise: Older Fetch implementations defaulted credentials to omit. Modern browsers default to same-origin, which means cookies flow on same-origin calls but not cross-origin. Set credentials: "include" explicitly for cross-origin auth.
  • Body can only be read once: Calling response.json() and then response.text() on the same Response throws. Call response.clone() before the first read if downstream code needs a second pass.
  • Mixed-content blocks fetch: A page served over HTTPS cannot fetch() an HTTP URL. The browser blocks the request without firing the catch handler in some builds, so test mixed-content paths early.

In my experience, the silent failure that costs the most production time is the "errors do not reject" rule. Wrap every fetch in a helper that throws on !response.ok before returning the parsed body, and your retry, logging, and alert paths all start working the way you expect.

...

Citations

All Fetch API version numbers and platform notes in this guide come from these primary sources:

Author

Prince Dewani is a Community Contributor at TestMu AI, where he manages content strategies around software testing, QA, and test automation. He is certified in Selenium, Cypress, Playwright, Appium, Automation Testing, and KaneAI. Prince has also presented academic research at the international conference PBCON-01. He further specializes in on-page SEO, bridging marketing with core testing technologies. On LinkedIn, he is followed by 4,300+ QA engineers, developers, DevOps experts, tech leaders, and AI-focused practitioners in the global testing community.

Open in ChatGPT Icon

Open in ChatGPT

Open in Claude Icon

Open in Claude

Open in Perplexity Icon

Open in Perplexity

Open in Grok Icon

Open in Grok

Open in Gemini AI Icon

Open in Gemini AI

Copied to Clipboard!
...

3000+ Browsers. One Platform.

See exactly how your site performs everywhere.

Try it free
...

Write Tests in Plain English with KaneAI

Create, debug, and evolve tests using natural language.

Try for free

Frequently asked questions

Did you find this page helpful?

More Related Hubs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests