- Notifications
You must be signed in to change notification settings - Fork2.8k
A window.fetch JavaScript polyfill.
License
JakeChampion/fetch
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Thefetch()
function is a Promise-based mechanism for programmatically makingweb requests in the browser. This project is a polyfill that implements a subsetof the standardFetch specification, enough to makefetch
a viablereplacement for most uses of XMLHttpRequest in traditional web applications.
If you believe you found a bug with how
fetch
behaves in your browser,pleasedon't open an issue in this repository unless you are testing inan old version of a browser that doesn't supportwindow.fetch
natively.Make sure you read thisentire readme, especially theCaveatssection, as there's probably a known work-around for an issue you've found.This project is apolyfill, and since all modern browsers now implement thefetch
function natively,no code from this project actually takes anyeffect there. SeeBrowser support for detailedinformation.If you have troublemaking a request to another domain (a differentsubdomain or port number also constitutes another domain), please familiarizeyourself with all the intricacies and limitations ofCORS requests.Because CORS requires participation of the server by implementing specificHTTP response headers, it is often nontrivial to set up or debug. CORS isexclusively handled by the browser's internal mechanisms which this polyfillcannot influence.
This projectdoesn't work under Node.js environments. It's meant for webbrowsers only. You should ensure that your application doesn't try to packageand run this on the server.
If you have an idea for a new feature of
fetch
,submit your featurerequests to thespecification's repository.We only add features and APIs that are part of theFetch specification.
npm install whatwg-fetch --save
You will also need a Promise polyfill forolder browsers.We recommendtaylorhakes/promise-polyfillfor its small size and Promises/A+ compatibility.
Importing will automatically polyfillwindow.fetch
and related APIs:
import'whatwg-fetch'window.fetch(...)
If for some reason you need to access the polyfill implementation, it isavailable via exports:
import{fetchasfetchPolyfill}from'whatwg-fetch'window.fetch(...)// use native browser versionfetchPolyfill(...)// use polyfill implementation
This approach can be used to, for example, useabortfunctionality in browsers that implement a native butoutdated version of fetch that doesn't support aborting.
For use with webpack, add this package in theentry
configuration optionbefore your application entry point:
entry:['whatwg-fetch', ...]
fetch('/users.html').then(function(response){returnresponse.text()}).then(function(body){document.body.innerHTML=body})
fetch('/users.json').then(function(response){returnresponse.json()}).then(function(json){console.log('parsed json',json)}).catch(function(ex){console.log('parsing failed',ex)})
fetch('/users.json').then(function(response){console.log(response.headers.get('Content-Type'))console.log(response.headers.get('Date'))console.log(response.status)console.log(response.statusText)})
varform=document.querySelector('form')fetch('/users',{method:'POST',body:newFormData(form)})
fetch('/users',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:'Hubot',login:'hubot',})})
varinput=document.querySelector('input[type="file"]')vardata=newFormData()data.append('file',input.files[0])data.append('user','hubot')fetch('/avatars',{method:'POST',body:data})
The Promise returned from
fetch()
won't reject on HTTP error statuseven if the response is an HTTP 404 or 500. Instead, it will resolve normally,and it will only reject on network failure or if anything prevented therequest from completing.For maximum browser compatibility when it comes to sending & receivingcookies, always supply the
credentials: 'same-origin'
option instead ofrelying on the default. SeeSending cookies.Not all Fetch standard options are supported in this polyfill. For instance,
redirect
andcache
directives are ignored.keepalive
is not supported because it would involve making a synchronous XHR, which is something this project is not willing to do. Seeissue #700 for more information.
To havefetch
Promise reject on HTTP error statuses, i.e. on any non-2xxstatus, define a custom response handler:
functioncheckStatus(response){if(response.status>=200&&response.status<300){returnresponse}else{varerror=newError(response.statusText)error.response=responsethrowerror}}functionparseJSON(response){returnresponse.json()}fetch('/users').then(checkStatus).then(parseJSON).then(function(data){console.log('request succeeded with JSON response',data)}).catch(function(error){console.log('request failed',error)})
ForCORS requests, usecredentials: 'include'
to allow sending credentialsto other domains:
fetch('https://example.com:1234/users',{credentials:'include'})
The default value forcredentials
is "same-origin".
The default forcredentials
wasn't always the same, though. The followingversions of browsers implemented an older version of the fetch specificationwhere the default was "omit":
- Firefox 39-60
- Chrome 42-67
- Safari 10.1-11.1.2
If you target these browsers, it's advisable to always specifycredentials: 'same-origin'
explicitly with all fetch requests instead of relying on thedefault:
fetch('/users',{credentials:'same-origin'})
Note: due tolimitations ofXMLHttpRequest,usingcredentials: 'omit'
is not respected for same domains in browsers wherethis polyfill is active. Cookies will always be sent to same domains in olderbrowsers.
As with XMLHttpRequest, theSet-Cookie
response header returned from theserver is aforbidden header name and therefore can't be programmaticallyread withresponse.headers.get()
. Instead, it's the browser's responsibilityto handle new cookies being set (if applicable to the current URL). Unless theyare HTTP-only, new cookies will be available throughdocument.cookie
.
The Fetch specification defines these values fortheredirect
option: "follow"(the default), "error", and "manual".
Due to limitations of XMLHttpRequest, only the "follow" mode is available inbrowsers where this polyfill is active.
Due to limitations of XMLHttpRequest, theresponse.url
value might not bereliable after HTTP redirects on older browsers.
The solution is to configure the server to set the response HTTP headerX-Request-URL
to the current URL after any redirect that might have happened.It should be safe to set it unconditionally.
# Ruby on Rails controller exampleresponse.headers['X-Request-URL']=request.url
This server workaround is necessary if you need reliableresponse.url
inFirefox < 32, Chrome < 37, Safari, or IE.
This polyfill supportsthe abortable fetch API.However, aborting a fetch requires use of two additional DOM APIs:AbortController andAbortSignal.Typically, browsers that do not support fetch will also not supportAbortController or AbortSignal. Consequently, you will need to includean additional polyfillfor these APIs to abort fetches:
import'yet-another-abortcontroller-polyfill'import{fetch}from'whatwg-fetch'// use native browser implementation if it supports abortingconstabortableFetch=('signal'innewRequest('')) ?window.fetch :fetchconstcontroller=newAbortController()abortableFetch('/avatars',{signal:controller.signal}).catch(function(ex){if(ex.name==='AbortError'){console.log('request aborted')}})// some time later...controller.abort()
- Chrome
- Firefox
- Safari 6.1+
- Internet Explorer 10+
Note: modern browsers such as Chrome, Firefox, Microsoft Edge, and Safari contain nativeimplementations ofwindow.fetch
, therefore the code from this polyfill doesn'thave any effect on those browsers. If you believe you've encountered an errorwith howwindow.fetch
is implemented in any of these browsers, you should filean issue with that browser vendor instead of this project.
About
A window.fetch JavaScript polyfill.
Topics
Resources
License
Code of conduct
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.