我有一个小型服务器和小型客户端。该代码已经外推,专注于手头的问题。
我有一个客户端向服务器发送POST请求。服务器以json对象响应。我无法从node.js客户端中看到json响应对象。但是,如果我提出卷曲请求,我可以看到它......
// SERVER
var restify = require('restify'),
Logger = require('bunyan'),
api = require('./routes/api'),
util = require('util'),
fs = require('fs');
//START SERVER
var server = restify.createServer({ name: 'image-server', log: log })
server.listen(7000, function () {
console.log('%s listening at %s', server.name, server.url)
})
server.use(restify.fullResponse());
server.use(restify.bodyParser());
//change from github
var user = {username: "usr", password: "pwd"};
//auth middleware
server.use(function(req,res,next){
if(req.params.username==user.username && req.params.password == user.password){
return next();
}else{
res.send(401);
}
});
server.post('/doc/', function(req,res){
var objToJson = {"result" : "success", "user" : "simon", "location" : "someloc"};
console.log("saved new doc. res: " + util.inspect(objToJson));
res.send(objToJson);
});
// CLIENT
var formdata = require('form-data');
var request = require('request');
var util = require('util');
var fs = require('fs');
var form = new formdata();
form.append('username', 'usr');
form.append('password', 'pwd');
form.append('user', 'someemail@gmail.com');
form.append('file', fs.createReadStream('/some/file.png'));
form.append('filename', "roger123131.png");
form.submit('http://0.0.0.0:7000/doc', function(err, res) {
console.log(res.statusCode);
console.log(res.body);
console.log( "here." + util.inspect(res));
process.exit();
});
在客户端,我使用表单数据模块。我需要发送文件,但我不确定这是否与手头的问题相关/相关。
// CURL REQUEST
curl -v --form username=usr --form password=pwd --form file=@/tmp/0000b.jpg --form user=someemail http://0.0.0.0:7000/doc
curl请求的输出有效。我的问题是,为什么我在我的node.js客户端代码中转储响应对象时看不到json响应,但我可以在使用curl发出请求时?我确定答案很简单......
编辑:这是node.js客户端的输出,显示没有json对象/字符串证据的响应对象:
200
undefined
here.{ _readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: true,
calledRead: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
objectMode: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events: { end: [Function: responseOnEnd], readable: [Function] },
_maxListeners: 10,
socket:
{ _connecting: false,
_handle:
{ fd: 10,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: true,
calledRead: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
objectMode: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
free: [Function],
close: [Object],
agentRemove: [Function],
drain: [Function: ondrain],
error: [Function: socketErrorListener] },
_maxListeners: 10,
_writableState:
{ highWaterMark: 16384,
objectMode: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
buffer: [],
errorEmitted: false },
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser:
{ _headers: [],
_url: '',
onHeaders: [Function: parserOnHeaders],
onHeadersComplete: [Function: parserOnHeadersComplete],
onBody: [Function: parserOnBody],
onMessageComplete: [Function: parserOnMessageComplete],
socket: [Circular],
incoming: [Circular],
maxHeaderPairs: 2000,
onIncoming: [Function: parserOnIncomingClient] },
_httpMessage:
{ domain: null,
_events: [Object],
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_headerSent: true,
_header: 'POST /doc HTTP/1.1\r\ncontent-type: multipart/form-data; boundary=--------------------------994987473640480876924123\r\nHost: 0.0.0.0:7000\r\nContent-Length: 23351\r\nConnection: keep-alive\r\n\r\n',
_hasBody: true,
_trailer: '',
finished: true,
_hangupClose: false,
socket: [Circular],
connection: [Circular],
agent: [Object],
socketPath: undefined,
method: 'POST',
path: '/doc',
_headers: [Object],
_headerNames: [Object],
parser: [Object],
res: [Circular] },
ondata: [Function: socketOnData] },
connection:
{ _connecting: false,
_handle:
{ fd: 10,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: true,
calledRead: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
objectMode: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
free: [Function],
close: [Object],
agentRemove: [Function],
drain: [Function: ondrain],
error: [Function: socketErrorListener] },
_maxListeners: 10,
_writableState:
{ highWaterMark: 16384,
objectMode: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
buffer: [],
errorEmitted: false },
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser:
{ _headers: [],
_url: '',
onHeaders: [Function: parserOnHeaders],
onHeadersComplete: [Function: parserOnHeadersComplete],
onBody: [Function: parserOnBody],
onMessageComplete: [Function: parserOnMessageComplete],
socket: [Circular],
incoming: [Circular],
maxHeaderPairs: 2000,
onIncoming: [Function: parserOnIncomingClient] },
_httpMessage:
{ domain: null,
_events: [Object],
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_headerSent: true,
_header: 'POST /doc HTTP/1.1\r\ncontent-type: multipart/form-data; boundary=--------------------------994987473640480876924123\r\nHost: 0.0.0.0:7000\r\nContent-Length: 23351\r\nConnection: keep-alive\r\n\r\n',
_hasBody: true,
_trailer: '',
finished: true,
_hangupClose: false,
socket: [Circular],
connection: [Circular],
agent: [Object],
socketPath: undefined,
method: 'POST',
path: '/doc',
_headers: [Object],
_headerNames: [Object],
parser: [Object],
res: [Circular] },
ondata: [Function: socketOnData] },
httpVersion: '1.1',
complete: false,
headers:
{ 'content-type': 'application/json',
'content-length': '56',
'access-control-allow-origin': '*',
'access-control-allow-headers': 'Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time',
'access-control-allow-methods': 'POST',
'access-control-expose-headers': 'Api-Version, Request-Id, Response-Time',
connection: 'Keep-Alive',
'content-md5': '/HLlB0jKu9S+l17eGyJfxg==',
date: 'Wed, 25 Jun 2014 15:40:00 GMT',
server: 'image-server',
'request-id': 'f7ca8390-fc7e-11e3-aa4e-e9c4573d9f1d',
'response-time': '4' },
trailers: {},
_pendings: [],
_pendingIndex: 0,
url: '',
method: null,
statusCode: 200,
client:
{ _connecting: false,
_handle:
{ fd: 10,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: true,
calledRead: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
objectMode: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
free: [Function],
close: [Object],
agentRemove: [Function],
drain: [Function: ondrain],
error: [Function: socketErrorListener] },
_maxListeners: 10,
_writableState:
{ highWaterMark: 16384,
objectMode: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
buffer: [],
errorEmitted: false },
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser:
{ _headers: [],
_url: '',
onHeaders: [Function: parserOnHeaders],
onHeadersComplete: [Function: parserOnHeadersComplete],
onBody: [Function: parserOnBody],
onMessageComplete: [Function: parserOnMessageComplete],
socket: [Circular],
incoming: [Circular],
maxHeaderPairs: 2000,
onIncoming: [Function: parserOnIncomingClient] },
_httpMessage:
{ domain: null,
_events: [Object],
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_headerSent: true,
_header: 'POST /doc HTTP/1.1\r\ncontent-type: multipart/form-data; boundary=--------------------------994987473640480876924123\r\nHost: 0.0.0.0:7000\r\nContent-Length: 23351\r\nConnection: keep-alive\r\n\r\n',
_hasBody: true,
_trailer: '',
finished: true,
_hangupClose: false,
socket: [Circular],
connection: [Circular],
agent: [Object],
socketPath: undefined,
method: 'POST',
path: '/doc',
_headers: [Object],
_headerNames: [Object],
parser: [Object],
res: [Circular] },
ondata: [Function: socketOnData] },
_consuming: true,
_dumped: false,
httpVersionMajor: 1,
httpVersionMinor: 1,
upgrade: false,
req:
{ domain: null,
_events: { error: [Object], response: [Function] },
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_headerSent: true,
_header: 'POST /doc HTTP/1.1\r\ncontent-type: multipart/form-data; boundary=--------------------------994987473640480876924123\r\nHost: 0.0.0.0:7000\r\nContent-Length: 23351\r\nConnection: keep-alive\r\n\r\n',
_hasBody: true,
_trailer: '',
finished: true,
_hangupClose: false,
socket:
{ _connecting: false,
_handle: [Object],
_readableState: [Object],
readable: true,
domain: null,
_events: [Object],
_maxListeners: 10,
_writableState: [Object],
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser: [Object],
_httpMessage: [Circular],
ondata: [Function: socketOnData] },
connection:
{ _connecting: false,
_handle: [Object],
_readableState: [Object],
readable: true,
domain: null,
_events: [Object],
_maxListeners: 10,
_writableState: [Object],
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser: [Object],
_httpMessage: [Circular],
ondata: [Function: socketOnData] },
agent:
{ domain: null,
_events: [Object],
_maxListeners: 10,
options: {},
requests: {},
sockets: [Object],
maxSockets: 5,
createConnection: [Function] },
socketPath: undefined,
method: 'POST',
path: '/doc',
_headers:
{ 'content-type': 'multipart/form-data; boundary=--------------------------994987473640480876924123',
host: '0.0.0.0:7000',
'content-length': 23351 },
_headerNames:
{ 'content-type': 'content-type',
host: 'Host',
'content-length': 'Content-Length' },
parser:
{ _headers: [],
_url: '',
onHeaders: [Function: parserOnHeaders],
onHeadersComplete: [Function: parserOnHeadersComplete],
onBody: [Function: parserOnBody],
onMessageComplete: [Function: parserOnMessageComplete],
socket: [Object],
incoming: [Circular],
maxHeaderPairs: 2000,
onIncoming: [Function: parserOnIncomingClient] },
res: [Circular] },
pipe: [Function],
addListener: [Function],
on: [Function],
pause: [Function],
resume: [Function],
read: [Function] }
答案 0 :(得分:0)
来自docs,
form.submit('http://example.org/', function(err, res) {
// res – response object (http.IncomingMessage) //
res.resume(); // for node-0.10.x
});
你的回调有三个参数,响应在第二个参数中。
答案 1 :(得分:0)
我在请求页面(https://github.com/mikeal/request)找到了一个解决方案,这需要对客户端代码进行少量更改:
var r = request.post('http://service.com/upload', function optionalCallback (err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
})
var form = r.form()
form.append('my_field', 'my_value')
form.append('my_buffer', new Buffer([1, 2, 3]))
form.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png')))
form.append('remote_file', request('http://google.com/doodle.png'))