Support for XHR responseType and response attributes

Summary:Currently the XMLHttpRequest don't support any response types other than text. This PR will add responseType attribute as well response attribute.

This PR will partially solve the issue https://github.com/facebook/react-native/issues/6017
Closes https://github.com/facebook/react-native/pull/6156

Differential Revision: D2994267

Pulled By: nicklockwood

fb-gh-sync-id: 24642c48655930c8350112bac38e6ed4a42bd40d
shipit-source-id: 24642c48655930c8350112bac38e6ed4a42bd40d
This commit is contained in:
Sreejumon 2016-03-01 09:35:14 -08:00 committed by Facebook Github Bot 7
parent c60ebf2660
commit cbc0e21926
1 changed files with 33 additions and 0 deletions

View File

@ -43,6 +43,8 @@ class XMLHttpRequestBase {
readyState: number; readyState: number;
responseHeaders: ?Object; responseHeaders: ?Object;
responseText: ?string; responseText: ?string;
response: string | ArrayBuffer | null;
responseType: '' | 'arraybuffer' | 'text';
status: number; status: number;
timeout: number; timeout: number;
responseURL: ?string; responseURL: ?string;
@ -83,6 +85,8 @@ class XMLHttpRequestBase {
this.readyState = this.UNSENT; this.readyState = this.UNSENT;
this.responseHeaders = undefined; this.responseHeaders = undefined;
this.responseText = ''; this.responseText = '';
this.response = null;
this.responseType = '';
this.status = 0; this.status = 0;
delete this.responseURL; delete this.responseURL;
@ -139,6 +143,15 @@ class XMLHttpRequestBase {
} }
} }
_stringToArrayBuffer(str: string): ArrayBuffer {
var buffer = new ArrayBuffer(str.length);
var bufferView = new Uint8Array(buffer);
for (var i = 0, l = str.length; i < l; i++) {
bufferView[i] = str.charCodeAt(i);
}
return buffer;
}
_didReceiveData(requestId: number, responseText: string): void { _didReceiveData(requestId: number, responseText: string): void {
if (requestId === this._requestId) { if (requestId === this._requestId) {
if (!this.responseText) { if (!this.responseText) {
@ -146,6 +159,17 @@ class XMLHttpRequestBase {
} else { } else {
this.responseText += responseText; this.responseText += responseText;
} }
switch(this.responseType) {
case '':
case 'text':
this.response = this.responseText;
break;
case 'arraybuffer': // NOTE: not supported by fetch
this.response = this._stringToArrayBuffer(this.responseText);
break;
default: //TODO: Support the other response type as well (eg:- document, json, blob)
this.response = null;
}
this.setReadyState(this.LOADING); this.setReadyState(this.LOADING);
} }
} }
@ -214,6 +238,12 @@ class XMLHttpRequestBase {
throw new Error('Subclass must define sendImpl method'); throw new Error('Subclass must define sendImpl method');
} }
_uintToString(uintArray: Int8Array): string {
// $FlowFixMe - Function.apply accepts Int8Array, but Flow thinks it doesn't
var encodedString = String.fromCharCode.apply(null, uintArray);
return decodeURIComponent(encodedString);
}
send(data: any): void { send(data: any): void {
if (this.readyState !== this.OPENED) { if (this.readyState !== this.OPENED) {
throw new Error('Request has not been opened'); throw new Error('Request has not been opened');
@ -222,6 +252,9 @@ class XMLHttpRequestBase {
throw new Error('Request has already been sent'); throw new Error('Request has already been sent');
} }
this._sent = true; this._sent = true;
if (data instanceof Int8Array) {
data = this._uintToString(data);
}
this.sendImpl(this._method, this._url, this._headers, data, this.timeout); this.sendImpl(this._method, this._url, this._headers, data, this.timeout);
} }