Better feature detection for FormData/FileReader/Blob
Summary: This PR bumps fetch to 0.9.0, the latest release and fixes broken feature detection originating in that self is not referring to `window.self` but an empty object. Assigning that object to window.self or GLOBAL won't work in the chrome dev tools because of CORS restrictions. This is a pragmatic solution but maybe not ideal. Background to the problem can be read here: https://github.com/facebook/react-native/issues/2376 Closes https://github.com/facebook/react-native/pull/2587 Reviewed By: @trunkagent, @svcscm Differential Revision: D2438341 Pulled By: @vjeux
This commit is contained in:
parent
69a4024c85
commit
7f76f08a11
|
@ -50,7 +50,7 @@ var self = {};
|
||||||
|
|
||||||
function normalizeName(name) {
|
function normalizeName(name) {
|
||||||
if (typeof name !== 'string') {
|
if (typeof name !== 'string') {
|
||||||
name = name.toString();
|
name = String(name)
|
||||||
}
|
}
|
||||||
if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
|
if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
|
||||||
throw new TypeError('Invalid character in header field name')
|
throw new TypeError('Invalid character in header field name')
|
||||||
|
@ -60,7 +60,7 @@ var self = {};
|
||||||
|
|
||||||
function normalizeValue(value) {
|
function normalizeValue(value) {
|
||||||
if (typeof value !== 'string') {
|
if (typeof value !== 'string') {
|
||||||
value = value.toString();
|
value = String(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
@ -68,18 +68,15 @@ var self = {};
|
||||||
function Headers(headers) {
|
function Headers(headers) {
|
||||||
this.map = {}
|
this.map = {}
|
||||||
|
|
||||||
var self = this
|
|
||||||
if (headers instanceof Headers) {
|
if (headers instanceof Headers) {
|
||||||
headers.forEach(function(name, values) {
|
headers.forEach(function(value, name) {
|
||||||
values.forEach(function(value) {
|
this.append(name, value)
|
||||||
self.append(name, value)
|
}, this)
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
} else if (headers) {
|
} else if (headers) {
|
||||||
Object.getOwnPropertyNames(headers).forEach(function(name) {
|
Object.getOwnPropertyNames(headers).forEach(function(name) {
|
||||||
self.append(name, headers[name])
|
this.append(name, headers[name])
|
||||||
})
|
}, this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,12 +112,12 @@ var self = {};
|
||||||
this.map[normalizeName(name)] = [normalizeValue(value)]
|
this.map[normalizeName(name)] = [normalizeValue(value)]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instead of iterable for now.
|
Headers.prototype.forEach = function(callback, thisArg) {
|
||||||
Headers.prototype.forEach = function(callback) {
|
|
||||||
var self = this
|
|
||||||
Object.getOwnPropertyNames(this.map).forEach(function(name) {
|
Object.getOwnPropertyNames(this.map).forEach(function(name) {
|
||||||
callback(name, self.map[name])
|
this.map[name].forEach(function(value) {
|
||||||
})
|
callback.call(thisArg, value, name, this)
|
||||||
|
}, this)
|
||||||
|
}, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
function consumed(body) {
|
function consumed(body) {
|
||||||
|
@ -154,7 +151,7 @@ var self = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
var support = {
|
var support = {
|
||||||
blob: 'FileReader' in self && 'Blob' in self && (function() {
|
blob: typeof FileReader === 'function' && typeof Blob === 'function' && (function() {
|
||||||
try {
|
try {
|
||||||
new Blob();
|
new Blob();
|
||||||
return true
|
return true
|
||||||
|
@ -162,7 +159,7 @@ var self = {};
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
})(),
|
})(),
|
||||||
formData: 'FormData' in self
|
formData: typeof FormData === 'function'
|
||||||
}
|
}
|
||||||
|
|
||||||
function Body() {
|
function Body() {
|
||||||
|
@ -246,20 +243,40 @@ var self = {};
|
||||||
return (methods.indexOf(upcased) > -1) ? upcased : method
|
return (methods.indexOf(upcased) > -1) ? upcased : method
|
||||||
}
|
}
|
||||||
|
|
||||||
function Request(url, options) {
|
function Request(input, options) {
|
||||||
options = options || {}
|
options = options || {}
|
||||||
this.url = url
|
var body = options.body
|
||||||
|
if (Request.prototype.isPrototypeOf(input)) {
|
||||||
|
if (input.bodyUsed) {
|
||||||
|
throw new TypeError('Already read')
|
||||||
|
}
|
||||||
|
this.url = input.url
|
||||||
|
this.credentials = input.credentials
|
||||||
|
if (!options.headers) {
|
||||||
|
this.headers = new Headers(input.headers)
|
||||||
|
}
|
||||||
|
this.method = input.method
|
||||||
|
this.mode = input.mode
|
||||||
|
if (!body) {
|
||||||
|
body = input._bodyInit
|
||||||
|
input.bodyUsed = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.url = input
|
||||||
|
}
|
||||||
|
|
||||||
this.credentials = options.credentials || 'omit'
|
this.credentials = options.credentials || this.credentials || 'omit'
|
||||||
this.headers = new Headers(options.headers)
|
if (options.headers || !this.headers) {
|
||||||
this.method = normalizeMethod(options.method || 'GET')
|
this.headers = new Headers(options.headers)
|
||||||
this.mode = options.mode || null
|
}
|
||||||
|
this.method = normalizeMethod(options.method || this.method || 'GET')
|
||||||
|
this.mode = options.mode || this.mode || null
|
||||||
this.referrer = null
|
this.referrer = null
|
||||||
|
|
||||||
if ((this.method === 'GET' || this.method === 'HEAD') && options.body) {
|
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
|
||||||
throw new TypeError('Body not allowed for GET or HEAD requests')
|
throw new TypeError('Body not allowed for GET or HEAD requests')
|
||||||
}
|
}
|
||||||
this._initBody(options.body)
|
this._initBody(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
function decode(body) {
|
function decode(body) {
|
||||||
|
@ -311,7 +328,6 @@ var self = {};
|
||||||
self.Response = Response;
|
self.Response = Response;
|
||||||
|
|
||||||
self.fetch = function(input, init) {
|
self.fetch = function(input, init) {
|
||||||
// TODO: Request constructor should accept input, init
|
|
||||||
var request
|
var request
|
||||||
if (Request.prototype.isPrototypeOf(input) && !init) {
|
if (Request.prototype.isPrototypeOf(input) && !init) {
|
||||||
request = input
|
request = input
|
||||||
|
@ -321,9 +337,6 @@ var self = {};
|
||||||
|
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
var xhr = new XMLHttpRequest()
|
var xhr = new XMLHttpRequest()
|
||||||
if (request.credentials === 'cors') {
|
|
||||||
xhr.withCredentials = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function responseURL() {
|
function responseURL() {
|
||||||
if ('responseURL' in xhr) {
|
if ('responseURL' in xhr) {
|
||||||
|
@ -360,14 +373,16 @@ var self = {};
|
||||||
|
|
||||||
xhr.open(request.method, request.url, true)
|
xhr.open(request.method, request.url, true)
|
||||||
|
|
||||||
|
if (request.credentials === 'include') {
|
||||||
|
xhr.withCredentials = true
|
||||||
|
}
|
||||||
|
|
||||||
if ('responseType' in xhr && support.blob) {
|
if ('responseType' in xhr && support.blob) {
|
||||||
xhr.responseType = 'blob'
|
xhr.responseType = 'blob'
|
||||||
}
|
}
|
||||||
|
|
||||||
request.headers.forEach(function(name, values) {
|
request.headers.forEach(function(value, name) {
|
||||||
values.forEach(function(value) {
|
xhr.setRequestHeader(name, value)
|
||||||
xhr.setRequestHeader(name, value)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
|
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
|
||||||
|
|
Loading…
Reference in New Issue