Skip to content

Instantly share code, notes, and snippets.

@sebringj
Created November 9, 2017 15:27
Show Gist options
  • Save sebringj/4f31439db6beb87ac32ecd74268411c0 to your computer and use it in GitHub Desktop.
Save sebringj/4f31439db6beb87ac32ecd74268411c0 to your computer and use it in GitHub Desktop.
React Native Fetch alternative with abort method attached to returned promise and timeout support
'use strict';
var self = this || global;
// Polyfill from https://github.com/github/fetch/blob/v1.1.1/fetch.js#L8-L21
var support = {
searchParams: 'URLSearchParams' in self,
iterable: 'Symbol' in self && 'iterator' in Symbol,
blob: 'FileReader' in self && 'Blob' in self && (function() {
try {
new Blob()
return true
} catch(e) {
return false
}
})(),
formData: 'FormData' in self,
arrayBuffer: 'ArrayBuffer' in self
}
// Polyfill from https://github.com/github/fetch/blob/v1.1.1/fetch.js#L364-L375
function parseHeaders(rawHeaders) {
var headers = new Headers()
rawHeaders.split(/\r?\n/).forEach(function(line) {
var parts = line.split(':')
var key = parts.shift().trim()
if (key) {
var value = parts.join(':').trim()
headers.append(key, value)
}
});
return headers;
}
// Polyfill from https://github.com/github/fetch/blob/v1.1.1/fetch.js#L424-L464
export default function fetchPolyfill (input, init) {
var xhr = new XMLHttpRequest()
var promise = new Promise(function(resolve, reject) {
var request = new Request(input, init)
/* @patch: timeout */
if (init.timeout) {
xhr.timeout = init.timeout;
}
/* @endpatch */
xhr.onload = function() {
var options = {
status: xhr.status,
statusText: xhr.statusText,
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
}
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')
var body = 'response' in xhr ? xhr.response : xhr.responseText
resolve(new Response(body, options))
}
xhr.onerror = function() {
reject(new TypeError('Network request failed'))
}
xhr.ontimeout = function() {
reject(new TypeError('Network request failed'))
}
xhr.open(request.method, request.url, true)
if (request.credentials === 'include') {
xhr.withCredentials = true
}
if ('responseType' in xhr && support.blob) {
xhr.responseType = 'blob'
}
request.headers.forEach(function(value, name) {
xhr.setRequestHeader(name, value)
})
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
})
promise.abort = () => xhr.abort()
return promise
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment