From c189b58e11f2a78e544e23ca061eebf5e458d722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 11 Nov 2016 19:32:14 +0100 Subject: [PATCH] Add support for ArrayBufferView as POST body Section 6.2 of the spec says that body can be BufferSource. BufferSource is defined in https://heycam.github.io/webidl/#BufferSource: > The BufferSource typedef is used to represent objects that are either > themselves an ArrayBuffer or which provide a view on to an ArrayBuffer. Furthermore, passing an ArrayBuffer directly to XMLHttpRequest is considered deprecated and Safari throws a warning about it. This makes it even more important to support ArrayBufferView in fetch. The fallback for `ArrayBuffer.isView` is provided for IE 10, which doesn't implement the method. --- fetch.js | 20 +++++++++++++++++++- test/test.js | 32 +++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/fetch.js b/fetch.js index c1ff6df..072f699 100644 --- a/fetch.js +++ b/fetch.js @@ -20,6 +20,24 @@ arrayBuffer: 'ArrayBuffer' in self } + if (support.arrayBuffer) { + var viewClasses = [ + '[object Int8Array]', + '[object Uint8Array]', + '[object Uint8ClampedArray]', + '[object Int16Array]', + '[object Uint16Array]', + '[object Int32Array]', + '[object Uint32Array]', + '[object Float32Array]', + '[object Float64Array]' + ] + + var isArrayBufferView = ArrayBuffer.isView || function(obj) { + return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1 + } + } + function normalizeName(name) { if (typeof name !== 'string') { name = String(name) @@ -177,7 +195,7 @@ this._bodyText = body.toString() } else if (!body) { this._bodyText = '' - } else if (support.arrayBuffer && ArrayBuffer.prototype.isPrototypeOf(body)) { + } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { // Only support ArrayBuffers for POST method. // Receiving ArrayBuffers happens via Blobs, instead. } else { diff --git a/test/test.js b/test/test.js index d5fb33f..320add7 100644 --- a/test/test.js +++ b/test/test.js @@ -868,15 +868,29 @@ suite('fetch method', function() { }) }) - featureDependent(test, support.arrayBuffer, 'sends ArrayBuffer body', function() { - return fetch('/request', { - method: 'post', - body: arrayBufferFromText('name=Hubot') - }).then(function(response) { - return response.json() - }).then(function(request) { - assert.equal(request.method, 'POST') - assert.equal(request.data, 'name=Hubot') + featureDependent(suite, support.arrayBuffer, 'ArrayBuffer', function() { + test('ArrayBuffer body', function() { + return fetch('/request', { + method: 'post', + body: arrayBufferFromText('name=Hubot') + }).then(function(response) { + return response.json() + }).then(function(request) { + assert.equal(request.method, 'POST') + assert.equal(request.data, 'name=Hubot') + }) + }) + + test('TypedArray body', function() { + return fetch('/request', { + method: 'post', + body: new Uint8Array(arrayBufferFromText('name=Hubot')) + }).then(function(response) { + return response.json() + }).then(function(request) { + assert.equal(request.method, 'POST') + assert.equal(request.data, 'name=Hubot') + }) }) })