diff --git a/README.md b/README.md index c19ac20..9be9114 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ type XhrOptions = String | { method: String?, timeout: Number?, headers: Object?, - body: String?, - json: Object?, + body: String||Object?, + json: Boolean?, username: String?, password: String?, withCredentials: Boolean?, @@ -148,6 +148,8 @@ Pass in body to be send across the [`XMLHttpRequest`][3]. Generally should be a string. But anything that's valid as a parameter to [`XMLHttpRequest.send`][1] should work (Buffer for file, etc.). +If `options.json` is `true`, then this must be a JSON-serializable object. + ### `options.uri` or `options.url` The uri to send a request to. Passed to [`XMLHttpRequest.open`][2]. `options.url` and `options.uri` are aliases for each other. @@ -163,8 +165,7 @@ Number of miliseconds to wait for response. Defaults to 0 (no timeout). Ignored ### `options.json` -A valid JSON serializable value to be send to the server. If this - is set then we serialize the value and use that as the body. +If set to `true` then we serialize the value of `options.body` and send that as the request body. We also set the Content-Type to `"application/json"`. Additionally the response body is parsed as JSON @@ -195,9 +196,11 @@ Pass an `XMLHttpRequest` object (or something that acts like one) to use instead - See `options.json` - you can set it to `true` on a GET request to tell `xhr` to parse the response body. - Without `options.json` body is returned as-is (a string or when `responseType` is set and the browser supports it - a result of parsing JSON or XML) - How do I send an object or array as POST body? - - `options.body` should be a string. You need to serialize your object before passing to `xhr` for sending. - - To serialize to JSON you can use - `options.json` instead of `options.body` for convenience - then `xhr` will do the serialization and set content-type accordingly. + - `options.body` should be a string or any other value that's valid as + a parameter to [`XMLHttpRequest.send`][1]. Any other value needs to + be serialized before passed to `xhr` for sending. + - To serialize to JSON you can set + `options.json` to `true` for convenience - then `xhr` will do the serialization and set content-type accordingly. - Where's stream API? `.pipe()` etc. - Not implemented. You can't reasonably have that in the browser. diff --git a/index.js b/index.js index a1deb4d..16d73cf 100644 --- a/index.js +++ b/index.js @@ -158,12 +158,12 @@ function _createXHR(options) { var isJson = false var timeoutTimer - if ("json" in options) { + if (options.json === true) { isJson = true headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user if (method !== "GET" && method !== "HEAD") { headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user - body = JSON.stringify(options.json) + body = JSON.stringify(options.body) } } diff --git a/test/index.js b/test/index.js index 689bff3..3fd1171 100644 --- a/test/index.js +++ b/test/index.js @@ -189,6 +189,16 @@ test("xhr[method] get, put, post, patch with url shorthands", function(assert) { }) }) +test("json encoded request body", function(assert) { + xhr.post("/mock/echo", { + json: true, + body: {foo: "bar"} + }, function(err, resp, body) { + assert.equal(resp.rawRequest.headers["Content-Type"], "application/json") + assert.deepEqual(body, {foo: "bar"}) + assert.end() + }) +}) test("xhr[method] get, put, post, patch with url shorthands and options", function(assert) { var i = 0 diff --git a/test/mock-server.js b/test/mock-server.js index 5d7d57d..913bdc2 100644 --- a/test/mock-server.js +++ b/test/mock-server.js @@ -6,6 +6,15 @@ module.exports = function (req, res) { } else if (req.url === '/mock/no-content') { res.statusCode = 204 res.end('') + } else if (req.url === '/mock/echo') { + var body = [] + req.on('data', function(chunk) { + body.push(chunk) + }) + req.on('end', function() { + res.statusCode = 200 + res.end(Buffer.concat(body).toString()) + }) } else if (req.url === '/mock/timeout') { setTimeout(function() { res.statusCode = 200