Skip to content

Commit 4eb5409

Browse files
committed
add support for binary and serialized object-data responses (arraybuffer/json responseType)
1 parent 525a28a commit 4eb5409

File tree

1 file changed

+58
-5
lines changed

1 file changed

+58
-5
lines changed

lib/index.js

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use strict';
22

3+
/* global ArrayBuffer */
4+
35
/**
46
* Node.js `XMLHttpRequest` implementation using `http.request()`.
57
*
@@ -24,7 +26,11 @@ var supportedResponseTypes = Object.freeze({
2426
/** Text response (implicit) */
2527
'': true,
2628
/** Text response */
27-
'text': true
29+
'text': true,
30+
/** Binary-data response */
31+
'arraybuffer': true,
32+
/** JSON response */
33+
'json': true
2834
});
2935

3036
/**
@@ -139,6 +145,14 @@ module.exports = function () {
139145
* @type {?String}
140146
*/
141147
this._responseText = null;
148+
149+
/**
150+
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response
151+
*
152+
* @private
153+
* @type {ArrayBuffer | String | Object}
154+
*/
155+
this._response = null;
142156
};
143157

144158
/** @alias module:node-http-xhr */
@@ -297,7 +311,15 @@ NodeHttpXHR.prototype = Object.create(
297311
throw new Error('Unsupported responseType "' + type + '"');
298312
}
299313

300-
return this._responseText;
314+
switch (type) {
315+
case '':
316+
case 'text':
317+
return this._responseText;
318+
case 'arraybuffer':
319+
return this._response;
320+
default:
321+
throw new Error('Assertion failed: unsupported response-type: ' + type);
322+
}
301323
}
302324
},
303325
/**
@@ -308,10 +330,19 @@ NodeHttpXHR.prototype = Object.create(
308330
* This will be incomplete until the response actually finishes.
309331
*
310332
* @type {?String}
333+
* @throws when `response` not a String
311334
* @readonly
312335
*/
313336
responseText: {
314-
get: function getResponseText() { return this._responseText; }
337+
get: function getResponseText() {
338+
339+
// @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText#Exceptions
340+
if (this._responseType !== 'text' && this._responseType !== '') {
341+
throw new Error('InvalidStateError: Response-type is ' + this._responseType);
342+
}
343+
344+
return this._responseText;
345+
}
315346
},
316347
/**
317348
* Indicates whether or not cross-site `Access-Control` requests should be
@@ -469,13 +500,35 @@ NodeHttpXHR.prototype.send = function (data) {
469500
this._resp = resp;
470501
this._responseText = '';
471502

472-
resp.setEncoding('utf8');
503+
// var contentType = resp.headers['content-type'];
504+
// TODO: adjust responseType from content-type header if applicable
505+
506+
// from Node API docs: The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.
507+
if (this._responseType === 'text' || this._responseType === '') {
508+
resp.setEncoding('utf8');
509+
}
510+
473511
resp.on('data', function onData(chunk) {
474-
this._responseText += chunk;
512+
513+
if (typeof chunk === 'string') {
514+
this._responseText += chunk;
515+
} else if (typeof chunk === 'object') {
516+
// binary data usually comes in one chunk (no chunky transfer-encoding)
517+
// or at least, that's what we'll support here for now
518+
if (chunk instanceof Buffer) {
519+
this._response = chunk.buffer;
520+
} else if (chunk instanceof ArrayBuffer) {
521+
this._response = chunk;
522+
} else {
523+
// JSON case
524+
this._response = chunk;
525+
}
526+
}
475527

476528
if (this.readyState !== this.LOADING) {
477529
this._setReadyState(this.LOADING);
478530
}
531+
479532
}.bind(this));
480533

481534
resp.on('end', function onEnd() {

0 commit comments

Comments
 (0)