{"id":7914,"date":"2015-11-09T01:56:04","date_gmt":"2015-11-09T01:56:04","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2015\/11\/09\/github-fetch\/"},"modified":"2015-11-09T01:56:04","modified_gmt":"2015-11-09T01:56:04","slug":"github-fetch","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2015\/11\/09\/github-fetch\/","title":{"rendered":"github\/fetch"},"content":{"rendered":"<p>The global <code>fetch<\/code> function is an easier way to make web requests and handle responses than using an XMLHttpRequest. This polyfill is written as closely as possible to the standard Fetch specification at https:\/\/fetch.spec.whatwg.org.<\/p>\n<h2>Installation<\/h2>\n<p>Available on Bower as <strong>fetch<\/strong>.<\/p>\n<pre><code>$ bower install fetch\n<\/code><\/pre>\n<p>You\u2019ll also need a Promise polyfill for older browsers.<\/p>\n<pre><code>$ bower install es6-promise\n<\/code><\/pre>\n<p>This can also be installed with <code>npm<\/code>.<\/p>\n<pre><code>$ npm install whatwg-fetch --save\n<\/code><\/pre>\n<p>(For a node.js implementation, try node-fetch)<\/p>\n<h2>Usage<\/h2>\n<p>The <code>fetch<\/code> function supports any HTTP method. We\u2019ll focus on GET and POST example requests.<\/p>\n<h3>HTML<\/h3>\n<pre><code>fetch('\/users.html')\n  .then(function(response) {\n    return response.text()\n  }).then(function(body) {\n    document.body.innerHTML = body\n  })\n<\/code><\/pre>\n<h3>JSON<\/h3>\n<pre><code>fetch('\/users.json')\n  .then(function(response) {\n    return response.json()\n  }).then(function(json) {\n    console.log('parsed json', json)\n  }).catch(function(ex) {\n    console.log('parsing failed', ex)\n  })\n<\/code><\/pre>\n<h3>Response metadata<\/h3>\n<pre><code>fetch('\/users.json').then(function(response) {\n  console.log(response.headers.get('Content-Type'))\n  console.log(response.headers.get('Date'))\n  console.log(response.status)\n  console.log(response.statusText)\n})\n<\/code><\/pre>\n<h3>Post form<\/h3>\n<pre><code>var form = document.querySelector('form')\n\nfetch('\/query', {\n  method: 'post',\n  body: new FormData(form)\n})\n<\/code><\/pre>\n<h3>Post JSON<\/h3>\n<pre><code>fetch('\/users', {\n  method: 'post',\n  headers: {\n    'Accept': 'application\/json',\n    'Content-Type': 'application\/json'\n  },\n  body: JSON.stringify({\n    name: 'Hubot',\n    login: 'hubot',\n  })\n})\n<\/code><\/pre>\n<h3>File upload<\/h3>\n<pre><code>var input = document.querySelector('input[type=\"file\"]')\n\nvar form = new FormData()\nform.append('file', input.files[0])\nform.append('user', 'hubot')\n\nfetch('\/avatars', {\n  method: 'post',\n  body: form\n})\n<\/code><\/pre>\n<h3>Success and error handlers<\/h3>\n<p>This causes <code>fetch<\/code> to behave like jQuery\u2019s <code>$.ajax<\/code> by rejecting the <code>Promise<\/code> on HTTP failure status codes like 404, 500, etc. The response <code>Promise<\/code> is resolved only on successful, 200 level, status codes.<\/p>\n<pre><code>function status(response) {\n  if (response.status &gt;= 200 &amp;&amp; response.status &lt; 300) {\n    return response\n  }\n  throw new Error(response.statusText)\n}\n\nfunction json(response) {\n  return response.json()\n}\n\nfetch('\/users')\n  .then(status)\n  .then(json)\n  .then(function(json) {\n    console.log('request succeeded with json response', json)\n  }).catch(function(error) {\n    console.log('request failed', error)\n  })\n<\/code><\/pre>\n<h3>Response URL caveat<\/h3>\n<p>The <code>Response<\/code> object has a URL attribute for the final responded resource. Usually this is the same as the <code>Request<\/code> url, but in the case of a redirect, its all transparent. Newer versions of XHR include a <code>responseURL<\/code> attribute that returns this value. But not every browser supports this. The compromise requires setting a special server side header to tell the browser what URL it just requested (yeah, I know browsers).<\/p>\n<pre><code>response.headers['X-Request-URL'] = request.url\n<\/code><\/pre>\n<p>If you want <code>response.url<\/code> to be reliable, you\u2019ll want to set this header. The day that you ditch this polyfill and use native fetch only, you can remove the header hack.<\/p>\n<h2>Browser Support<\/h2>\n<table>\n<tr>\n<th><img decoding=\"async\" src=\"http:\/\/raw.github.com\/alrra\/browser-logos\/master\/chrome\/chrome_48x48.png\" \/><\/th>\n<th><img decoding=\"async\" src=\"http:\/\/raw.github.com\/alrra\/browser-logos\/master\/firefox\/firefox_48x48.png\" \/><\/th>\n<th><img decoding=\"async\" src=\"http:\/\/raw.github.com\/alrra\/browser-logos\/master\/internet-explorer\/internet-explorer_48x48.png\" \/><\/th>\n<th><img decoding=\"async\" src=\"http:\/\/raw.github.com\/alrra\/browser-logos\/master\/opera\/opera_48x48.png\" \/><\/th>\n<th><img decoding=\"async\" src=\"http:\/\/raw.github.com\/alrra\/browser-logos\/master\/safari\/safari_48x48.png\" \/><\/th>\n<\/tr>\n<tr>\n<td>Latest \u2714<\/td>\n<td>Latest \u2714<\/td>\n<td>9+ \u2714<\/td>\n<td>Latest \u2714<\/td>\n<td>6.1+ \u2714<\/td>\n<\/tr>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>The global fetch function is an easier way to make web requests and handle responses than using an XMLHttpRequest. This polyfill is written as closely as possible to the standard Fetch specification at https:\/\/fetch.spec.whatwg.org. Installation Available on Bower as fetch. $ bower install fetch You\u2019ll also need a Promise polyfill for older browsers. $ bower [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7914","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/7914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=7914"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/7914\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=7914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=7914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=7914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}