How is an HTTP POST request made in node.js?
如何在node.js中使用数据发出出站HTTP POST请求?
如果使用请求库,这会变得容易得多。
1 2 3 4 5 6 7 8 9 10 11 | var request = require('request'); request.post( 'http://www.yoursite.com/formpage', { json: { key: 'value' } }, function (error, response, body) { if (!error && response.statusCode == 200) { console.log(body); } } ); |
除了提供良好的语法之外,它还可以简化JSON请求,处理OAuth签名(用于Twitter等),可以执行多部分表单(例如用于上载文件)和流式处理。
要安装请求,请使用命令
下面是使用node.js向Google编译器API发出POST请求的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | // We need this to build our post string var querystring = require('querystring'); var http = require('http'); var fs = require('fs'); function PostCode(codestring) { // Build the post string from an object var post_data = querystring.stringify({ 'compilation_level' : 'ADVANCED_OPTIMIZATIONS', 'output_format': 'json', 'output_info': 'compiled_code', 'warning_level' : 'QUIET', 'js_code' : codestring }); // An object of options to indicate where to post to var post_options = { host: 'closure-compiler.appspot.com', port: '80', path: '/compile', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(post_data) } }; // Set up the request var post_req = http.request(post_options, function(res) { res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('Response: ' + chunk); }); }); // post the data post_req.write(post_data); post_req.end(); } // This is an async file read fs.readFile('LinkedList.js', 'utf-8', function (err, data) { if (err) { // If this were just a small part of the application, you would // want to handle this differently, maybe throwing an exception // for the caller to handle. Since the file is absolutely essential // to the program's functionality, we're going to exit with a fatal // error instead. console.log("FATAL An error occurred trying to read in the file:" + err); process.exit(-2); } // Make sure there's data before we post it if(data) { PostCode(data); } else { console.log("No data to post"); process.exit(-1); } }); |
我已经更新了代码来显示如何从文件中发布数据,而不是硬编码字符串。它使用async
您可以使用请求库。网址:https://www.npmjs.com/package/request
1 | var request = require('request'); |
发布JSON数据:
1 2 3 4 5 6 7 8 9 | var myJSONObject = { ... }; request({ url:"http://josiahchoi.com/myjson", method:"POST", json: true, // <--Very important!!! body: myJSONObject }, function (error, response, body){ console.log(response); }); |
要发布XML数据:
1 2 3 4 5 6 7 8 9 10 11 | var myXMLText = '<xml>...........</xml>' request({ url:"http://josiahchoi.com/myjson", method:"POST", headers: { "content-type":"application/xml", // <--Very important!!! }, body: myXMLText }, function (error, response, body){ console.log(response); }); |
我用刀架和针来生产。它们都比本地httprequest强大得多。可以通过基本身份验证、特殊的头条目甚至上传/下载文件来请求。
至于post/get操作,它们的使用也比使用httpRequest的原始Ajax调用简单得多。
1 2 3 4 | needle.post('https://my.app.com/endpoint', {foo:'bar'}, function(err, resp, body){ console.log(body); }); |
您还可以使用Requestify,这是我为nodejs+编写的一个非常酷和简单的HTTP客户端,它支持缓存。
只需执行以下操作:
1 2 3 4 5 6 7 8 9 | var requestify = require('requestify'); requestify.post('http://example.com', { hello: 'world' }) .then(function(response) { // Get the response body (JSON parsed or jQuery object for XMLs) response.getBody(); }); |
简单且不依赖。使用承诺,以便您可以等待结果。它返回响应主体,不检查响应状态代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | const https = require('https'); function httpsPost({body, ...options}) { return new Promise((resolve,reject) => { const req = https.request({ method: 'POST', ...options, }, res => { const chunks = []; res.on('data', data => chunks.push(data)) res.on('end', () => { let body = Buffer.concat(chunks); switch(res.headers['content-type']) { case 'application/json': body = JSON.parse(body); break; } resolve(body) }) }) req.on('error',reject); if(body) { req.write(body); } req.end(); }) } |
用途:
1 2 3 4 5 6 7 8 9 10 11 | const res = await httpsPost({ hostname: 'sentry.io', path: `/api/0/organizations/org/releases/${changesetId}/deploys/`, headers: { 'Authorization': `Bearer ${process.env.SENTRY_AUTH_TOKEN}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ environment: isLive ? 'production' : 'demo', }) }) |
为那些晚年来这里的人。现在有很多不同的库可以用最少的编码来完成这个任务。我更喜欢优雅的轻量级库来处理HTTP请求,除非您绝对需要控制低级别的HTTP内容。
这样的图书馆是独一无二的
要安装它,请使用
以及每个人都习惯的
1 2 3 4 5 6 7 8 | var unirest = require('unirest'); unirest.post('http://example.com/helloworld') .header('Accept', 'application/json') .send({"Hello":"World!" }) .end(function (response) { console.log(response.body); }); |
额外的:很多人也建议使用请求[2]
值得注意的是,在幕后,
Unirest提供直接访问请求对象的方法。
例子:
1 | var Request = unirest.get('http://mockbin.com/request'); |
这是我用来发出请求的最简单方法:使用"请求"模块。
安装"请求"模块的命令:
1 | $ npm install request |
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | var request = require('request') var options = { method: 'post', body: postData, // Javascript object json: true, // Use,If you are sending JSON data url: url, headers: { // Specify headers, If any } } request(options, function (err, res, body) { if (err) { console.log('Error :', err) return } console.log(' Body :', body) }); |
您还可以使用node.js的内置"http"模块发出请求。
我喜欢超级代理的简单性(https://github.com/visionmedia/superagent)。节点和浏览器上的API相同。
1 2 3 4 | ;(async function() { var response = await superagent.post('http://127.0.0.1:8125/', {age: 2}) console.log(response) }) |
还有node fetch(https://www.npmjs.com/package/node fetch),它有一个与浏览器中的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | var https = require('https'); /** * HOW TO Make an HTTP Call - POST */ // do a POST request // create the JSON object jsonObject = JSON.stringify({ "message" :"The web of things is approaching, let do some tests to be ready!", "name" :"Test message posted with node.js", "caption" :"Some tests with node.js", "link" :"http://www.youscada.com", "description" :"this is a description", "picture" :"http://youscada.com/wp-content/uploads/2012/05/logo2.png", "actions" : [ { "name" :"youSCADA", "link" :"http://www.youscada.com" } ] }); // prepare the header var postheaders = { 'Content-Type' : 'application/json', 'Content-Length' : Buffer.byteLength(jsonObject, 'utf8') }; // the post options var optionspost = { host : 'graph.facebook.com', port : 443, path : '/youscada/feed?access_token=your_api_key', method : 'POST', headers : postheaders }; console.info('Options prepared:'); console.info(optionspost); console.info('Do the POST call'); // do the POST call var reqPost = https.request(optionspost, function(res) { console.log("statusCode:", res.statusCode); // uncomment it for header details // console.log("headers:", res.headers); res.on('data', function(d) { console.info('POST result: '); process.stdout.write(d); console.info(' POST completed'); }); }); // write the json data reqPost.write(jsonObject); reqPost.end(); reqPost.on('error', function(e) { console.error(e); }); |
如果您正在寻找基于Promise的HTTP请求,AXIOS可以很好地完成它的工作。
1 2 3 4 5 | const axios = require('axios'); axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'}) .then((response) => console.log(response)) .catch((error) => console.log(error)); |
或
1 | await axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'}) |
发布REST/JSON请求我们可以简单地使用请求包并保存在JSON变量中必须发送的值。
首先在控制台中安装所需软件包NPM安装请求--保存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var request = require('request'); var options={ 'key':'28', 'key1':'value', 'key2':'value' } request({ url:"http://dev.api.ean.com/ean-services/rs/hotel/v3/ping? minorRev="+options.key+ "&cid="+options.key1+ "&apiKey="+options.key2, method:"POST", json:true},function(error,response,body){ console.log(body) } ); |
我发现了一段视频,解释了如何实现这个目标:https://www.youtube.com/watch?V= NUW48U3YRG
它使用默认的"http"模块和"querystring"和"stringbuilder"模块。应用程序从网页中获取两个数字(使用两个文本框),提交后返回这两个数字的和(以及在文本框中保留值)。这是我在其他地方能找到的最好的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | var http = require("http"); var qs = require("querystring"); var StringBuilder = require("stringbuilder"); var port = 9000; function getCalcHtml(req, resp, data) { var sb = new StringBuilder({ newline:" " }); sb.appendLine("<html>"); sb.appendLine(" <body>"); sb.appendLine(" <form method='post'>"); sb.appendLine(" <table>"); sb.appendLine(" <tr>"); sb.appendLine(" <td>Enter First No: </td>"); if (data && data.txtFirstNo) { sb.appendLine(" <td><input type='text' id='txtFirstNo' name='txtFirstNo' value='{0}'/></td>", data.txtFirstNo); } else { sb.appendLine(" <td><input type='text' id='txtFirstNo' name='txtFirstNo' /></td>"); } sb.appendLine(" </tr>"); sb.appendLine(" <tr>"); sb.appendLine(" <td>Enter Second No: </td>"); if (data && data.txtSecondNo) { sb.appendLine(" <td><input type='text' id='txtSecondNo' name='txtSecondNo' value='{0}'/></td>", data.txtSecondNo); } else { sb.appendLine(" <td><input type='text' id='txtSecondNo' name='txtSecondNo' /></td>"); } sb.appendLine(" </tr>"); sb.appendLine(" <tr>"); sb.appendLine(" <td><input type='submit' value='Calculate' /></td>"); sb.appendLine(" </tr>"); if (data && data.txtFirstNo && data.txtSecondNo) { var sum = parseInt(data.txtFirstNo) + parseInt(data.txtSecondNo); sb.appendLine(" <tr>"); sb.appendLine(" <td>Sum: {0}</td>", sum); sb.appendLine(" </tr>"); } sb.appendLine(" </table>"); sb.appendLine(" </form>") sb.appendLine(" </body>"); sb.appendLine("</html>"); sb.build(function (err, result) { resp.write(result); resp.end(); }); } function getCalcForm(req, resp, data) { resp.writeHead(200, {"Content-Type":"text/html" }); getCalcHtml(req, resp, data); } function getHome(req, resp) { resp.writeHead(200, {"Content-Type":"text/html" }); resp.write("<html><html><head>Home</head><body>Want to some calculation? Click here</body></html>"); resp.end(); } function get404(req, resp) { resp.writeHead(404,"Resource Not Found", {"Content-Type":"text/html" }); resp.write("<html><html><head>404</head><body>404: Resource not found. Go to Home</body></html>"); resp.end(); } function get405(req, resp) { resp.writeHead(405,"Method not supported", {"Content-Type":"text/html" }); resp.write("<html><html><head>405</head><body>405: Method not supported</body></html>"); resp.end(); } http.createServer(function (req, resp) { switch (req.method) { case"GET": if (req.url ==="/") { getHome(req, resp); } else if (req.url ==="/calc") { getCalcForm(req, resp); } else { get404(req, resp); } break; case"POST": if (req.url ==="/calc") { var reqBody = ''; req.on('data', function (data) { reqBody += data; if (reqBody.length > 1e7) { //10MB resp.writeHead(413, 'Request Entity Too Large', { 'Content-Type': 'text/html' }); resp.end('<!doctype html><html><head>413</head><body>413: Request Entity Too Large</body></html>'); } }); req.on('end', function () { var formData = qs.parse(reqBody); getCalcForm(req, resp, formData); }); } else { get404(req, resp); } break; default: get405(req, resp); break; } }).listen(port); |
在创建了一个低级别的实用程序来处理post和获取我的项目的请求时,我费了很大的劲,然后决定将我的工作发布到这里。在接受回答的许多行中,这里有一个用于发送JSON数据的HTTP和HTTPS POST请求的片段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | const http = require("http") const https = require("https") // Request handler function let postJSON = (options, postData, callback) => { // Serializing JSON post_data = JSON.stringify(postData) let port = options.port == 443 ? https : http // Callback function for the request let req = port.request(options, (res) => { let output = '' res.setEncoding('utf8') // Listener to receive data res.on('data', (chunk) => { output += chunk }); // Listener for intializing callback after receiving complete response res.on('end', () => { let obj = JSON.parse(output) callback(res.statusCode, obj) }); }); // Handle any errors occurred while making request req.on('error', (err) => { //res.send('error: ' + err.message) }); // Request is made here, with data as string or buffer req.write(post_data) // Ending the request req.end() }; let callPost = () => { let data = { 'name': 'Jon', 'message': 'hello, world' } let options = { host: 'domain.name', // Your domain name port: 443, // 443 for https and 80 for http path: '/path/to/resource', // Path for the request method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) } } postJSON(options, data, (statusCode, result) => { // Handle response // Process the received data }); } |
这是我对
关于
如果主体是一个JSON对象,那么用
1 2 3 4 | var bodyString=JSON.stringify(body) var _headers = { 'Content-Length': Buffer.byteLength(bodyString) }; |
在将其写入请求之前:
1 | request.write( bodyString ); |
关于
1 2 3 4 5 6 7 | request.on('socket', function (socket) { socket.setTimeout( self.timeout ); socket.on('timeout', function() { request.abort(); if(timeout) return timeout( new Error('request timed out') ); }); }); |
而
1 2 3 4 5 6 7 8 | request.on('timeout', function () { // Timeout happend. Server received request, but not handled it // (i.e. doesn't send any response or it took to long). // You don't know what happend. // It will emit 'error' message as well (with ECONNRESET code). req.abort(); if(timeout) return timeout( new Error('request timed out') ); }); |
我强烈建议注册这两个处理程序。
响应体是分块的,因此您必须在
1 2 3 4 | var body = ''; response.on('data', function(d) { body += d; }); |
在
1 2 3 4 5 6 7 8 | response.on('end', function() { try { var jsonResponse=JSON.parse(body); if(success) return success( jsonResponse ); } catch(ex) { // bad json if(error) return error(ex.toString()); } }); |
用
模块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | /** * Simple POST and GET * @author Loreto Parisi (loretoparisi at gmail dot com) */ (function() { var SimpleAPI; SimpleAPI = (function() { var qs = require('querystring'); /** * API Object model * @author Loreto Parisi (loretoparisi at gmail dot com) */ function SimpleAPI(host,port,timeout,ssl,debug,json) { this.host=host; this.port=port; this.timeout=timeout; /** true to use ssl - defaults to true */ this.ssl=ssl || true; /** true to console log */ this.debug=debug; /** true to parse response as json - defaults to true */ this.json= (typeof(json)!='undefined')?json:true; this.requestUrl=''; if(ssl) { // use ssl this.http = require('https'); } else { // go unsafe, debug only please this.http = require('http'); } } /** * HTTP GET * @author Loreto Parisi (loretoparisi at gmail dot com) */ SimpleAPI.prototype.Get = function(path, headers, params, success, error, timeout) { var self=this; if(params) { var queryString=qs.stringify(params); if( queryString ) { path+="?"+queryString; } } var options = { headers : headers, hostname: this.host, path: path, method: 'GET' }; if(this.port && this.port!='80') { // port only if ! 80 options['port']=this.port; } if(self.debug) { console.log("SimpleAPI.Get", headers, params, options ); } var request=this.http.get(options, function(response) { if(self.debug) { // debug console.log( JSON.stringify(response.headers) ); } // Continuously update stream with data var body = ''; response.on('data', function(d) { body += d; }); response.on('end', function() { try { if(self.json) { var jsonResponse=JSON.parse(body); if(success) return success( jsonResponse ); } else { if(success) return success( body ); } } catch(ex) { // bad json if(error) return error( ex.toString() ); } }); }); request.on('socket', function (socket) { socket.setTimeout( self.timeout ); socket.on('timeout', function() { request.abort(); if(timeout) return timeout( new Error('request timed out') ); }); }); request.on('error', function (e) { // General error, i.e. // - ECONNRESET - server closed the socket unexpectedly // - ECONNREFUSED - server did not listen // - HPE_INVALID_VERSION // - HPE_INVALID_STATUS // - ... (other HPE_* codes) - server returned garbage console.log(e); if(error) return error(e); }); request.on('timeout', function () { // Timeout happend. Server received request, but not handled it // (i.e. doesn't send any response or it took to long). // You don't know what happend. // It will emit 'error' message as well (with ECONNRESET code). req.abort(); if(timeout) return timeout( new Error('request timed out') ); }); self.requestUrl = (this.ssl?'https':'http') + '://' + request._headers['host'] + request.path; if(self.debug) { console.log("SimpleAPI.Post",self.requestUrl); } request.end(); } //RequestGet /** * HTTP POST * @author Loreto Parisi (loretoparisi at gmail dot com) */ SimpleAPI.prototype.Post = function(path, headers, params, body, success, error, timeout) { var self=this; if(params) { var queryString=qs.stringify(params); if( queryString ) { path+="?"+queryString; } } var bodyString=JSON.stringify(body) var _headers = { 'Content-Length': Buffer.byteLength(bodyString) }; for (var attrname in headers) { _headers[attrname] = headers[attrname]; } var options = { headers : _headers, hostname: this.host, path: path, method: 'POST', qs : qs.stringify(params) }; if(this.port && this.port!='80') { // port only if ! 80 options['port']=this.port; } if(self.debug) { console.log("SimpleAPI.Post %s %s", JSON.stringify(_headers,null,2), JSON.stringify(options,null,2) ); } if(self.debug) { console.log("SimpleAPI.Post body %s", JSON.stringify(body,null,2) ); } var request=this.http.request(options, function(response) { if(self.debug) { // debug console.log( JSON.stringify(response.headers) ); } // Continuously update stream with data var body = ''; response.on('data', function(d) { body += d; }); response.on('end', function() { try { console.log("END", body); var jsonResponse=JSON.parse(body); if(success) return success( jsonResponse ); } catch(ex) { // bad json if(error) return error(ex.toString()); } }); }); request.on('socket', function (socket) { socket.setTimeout( self.timeout ); socket.on('timeout', function() { request.abort(); if(timeout) return timeout( new Error('request timed out') ); }); }); request.on('error', function (e) { // General error, i.e. // - ECONNRESET - server closed the socket unexpectedly // - ECONNREFUSED - server did not listen // - HPE_INVALID_VERSION // - HPE_INVALID_STATUS // - ... (other HPE_* codes) - server returned garbage console.log(e); if(error) return error(e); }); request.on('timeout', function () { // Timeout happend. Server received request, but not handled it // (i.e. doesn't send any response or it took to long). // You don't know what happend. // It will emit 'error' message as well (with ECONNRESET code). req.abort(); if(timeout) return timeout( new Error('request timed out') ); }); self.requestUrl = (this.ssl?'https':'http') + '://' + request._headers['host'] + request.path; if(self.debug) { console.log("SimpleAPI.Post",self.requestUrl); } request.write( bodyString ); request.end(); } //RequestPost return SimpleAPI; })(); module.exports = SimpleAPI }).call(this); |
用途:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // Parameters // domain: example.com // ssl:true, port:80 // timeout: 30 secs // debug: true // json response:true var api = new SimpleAPI('posttestserver.com', 80, 1000 * 10, true, true, true); var headers = { 'Content-Type' : 'application/json', 'Accept' : 'application/json' }; var params = { "dir" :"post-test" }; var method = 'post.php'; api.Post(method, headers, params, body , function(response) { // success console.log( response ); } , function(error) { // error console.log( error.toString() ); } , function(error) { // timeout console.log( new Error('timeout error') ); }); |
发布AXIOS.POST请求的另一个AXIOS示例,该请求使用其他配置选项和自定义头。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | var postData = { email:"[email protected]", password:"password" }; let axiosConfig = { headers: { 'Content-Type': 'application/json;charset=UTF-8', "Access-Control-Allow-Origin":"*", } }; axios.post('http://<host>:<port>/<path>', postData, axiosConfig) .then((res) => { console.log("RESPONSE RECEIVED:", res); }) .catch((err) => { console.log("AXIOS ERROR:", err); }) |
1 2 3 4 5 6 7 8 9 10 | let request = require('request'); let jsonObj = {}; request({ url:"https://myapii.com/sendJsonData", method:"POST", json: true, body: jsonObj }, function (error, resp, body){ console.log(resp); }); |
或者您可以使用此库:
1 2 3 4 5 6 7 8 9 10 11 12 | let axios = require("axios"); let jsonObj = {}; const myJsonAPI = axios.create({ baseURL: 'https://myapii.com', timeout: 120*1000 }); let response = await myJsonAPI.post("sendJsonData",jsonobj).catch(e=>{ res.json(e); }); console.log(response); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var options = { method: 'POST', uri: 'http://api.posttestserver.com/post', body: { some: 'payload' }, json: true // Automatically stringifies the body to JSON }; rp(options) .then(function (parsedBody) { // POST succeeded... }) .catch(function (err) { // POST failed... }); |
通过使用请求依赖关系。
简单解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import request from 'request' var data = { "host":"127.1.1.1", "port":9008 } request.post( baseUrl + '/peers/connect', { json: data, // your payload data placed here headers: { 'X-Api-Key': 'dajzmj6gfuzmbfnhamsbuxivc', // if authentication needed 'Content-Type': 'application/json' } }, function (error, response, body) { if (error) { callback(error, null) } else { callback(error, response.body) } }); |