From cbc0e21926594cbe650db34c466b934fda5c13ef Mon Sep 17 00:00:00 2001 From: Sreejumon Date: Tue, 1 Mar 2016 09:35:14 -0800 Subject: [PATCH] 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 --- Libraries/Network/XMLHttpRequestBase.js | 33 +++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Libraries/Network/XMLHttpRequestBase.js b/Libraries/Network/XMLHttpRequestBase.js index 14e284ae5..96d2ec1d2 100644 --- a/Libraries/Network/XMLHttpRequestBase.js +++ b/Libraries/Network/XMLHttpRequestBase.js @@ -43,6 +43,8 @@ class XMLHttpRequestBase { readyState: number; responseHeaders: ?Object; responseText: ?string; + response: string | ArrayBuffer | null; + responseType: '' | 'arraybuffer' | 'text'; status: number; timeout: number; responseURL: ?string; @@ -83,6 +85,8 @@ class XMLHttpRequestBase { this.readyState = this.UNSENT; this.responseHeaders = undefined; this.responseText = ''; + this.response = null; + this.responseType = ''; this.status = 0; 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 { if (requestId === this._requestId) { if (!this.responseText) { @@ -146,6 +159,17 @@ class XMLHttpRequestBase { } else { 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); } } @@ -214,6 +238,12 @@ class XMLHttpRequestBase { 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 { if (this.readyState !== this.OPENED) { throw new Error('Request has not been opened'); @@ -222,6 +252,9 @@ class XMLHttpRequestBase { throw new Error('Request has already been sent'); } this._sent = true; + if (data instanceof Int8Array) { + data = this._uintToString(data); + } this.sendImpl(this._method, this._url, this._headers, data, this.timeout); }