我尝试将带有来自node.js的POST请求的* .wgt文件(有效的* .zip文件)发送到运行Wookie Server的其他服务器。我已经关注了 http服务器和 fs 的node.js文档以及stackoverflow上的另外两篇帖子(Node.js POST File to Server和how to upload a file from node.js)但我没有设法使其发挥作用。
我已经做过的事情:
我有* .wgt文件存储在node.js服务器上。我在节点中创建一个http服务器,准备对Wookie REST API的POST请求,获取带有fs.createReadStream()
的* .zip文件流,然后用pipe()
对其进行流式处理。但我得到以下错误响应:
错误:找不到上传到服务器的文件。请求发送的请求 客户端在语法上是incorect(没有文件上传到服务器)。
此特定请求的Wookie Server API参考如下所示:
POST {wookie} / widgets {file} - 将小部件添加到服务器。该方法在响应中回显窗口小部件元数据。
我的代码如下:
var http = require('http');
var fs = require('fs');
var file_name = 'test.wgt';
// auth data for access to the wookie server api
var username = 'java';
var password = 'java';
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
// boundary key for post request
var boundaryKey = Math.random().toString(16);
var wookieResponse = "";
// take content length of the request body: see https://stackoverflow.com/questions/9943010/node-js-post-file-to-server
var body_before_file =
'--' + boundaryKey + '\r\n'
+ 'Content-Type: application/octet-stream\r\n'
+ 'Content-Disposition: form-data; name="file"; filename="'+file_name+'"\r\n'
+ 'Content-Transfer-Encoding: binary\r\n\r\n';
var body_after_file = "--"+boundaryKey+"--\r\n\r\n";
fs.stat('./uploads/'+file_name, function(err, file_info) {
console.log(Buffer.byteLength(body_before_file) +"+"+ file_info.size +"+"+ Buffer.byteLength(body_after_file));
var content_length = Buffer.byteLength(body_before_file) +
file_info.size +
Buffer.byteLength(body_after_file);
// set content length and other values to the header
var header = {
'Authorization': auth,
'Content-Length': String(content_length),
'Accept': '*/*',
'Content-Type': 'multipart/form-data; boundary="--'+boundaryKey+'"',//,
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Charset': 'ISO-8859-2,utf-8;q=0.7,*;q=0.3'
};
// set request options
var options = {
host: appOptions.hostWP,
port: 8080,
path: '/wookie/widgets',
method: 'POST',
headers: header
};
// create http request
var requ = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
wookieResponse = wookieResponse + chunk;
});
res.on('end', function (chunk) {
wookieResponse = wookieResponse + chunk;
console.log(wookieResponse);
})
});
// write body_before_file (see above) to the body request
requ.write(body_before_file);
// prepare createReadStream and pipe it to the request
var fileStream = fs.createReadStream('./uploads/'+file_name);
fileStream.pipe(requ, {end: false});
// finish request with boundaryKey
fileStream.on('end', function() {
requ.end('--' + boundaryKey + '--\r\n\r\n');
});
requ.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
});
我做错了什么,如何通过来自node.js的POST请求获得正确的* .wgt / * .zip文件上传?
干杯, 米甲
答案 0 :(得分:2)
我实现了所讨论的目标:将带有* .zip / * .wgt文件的node.js的POST请求发送到另一台服务器。
我没有使用问题中引入的方法来管理:使用请求模块逐步构建请求。我做了一些研究,我找到了intersting node.js模块:form-data。这个模块做什么? Readme.md说:
用于创建可读“multipart / form-data”流的模块。可以用 将表单和文件上传提交到其他Web应用程序。
在列举的示例中,我发现了以下示例:
var CRLF = '\r\n';
var form = new FormData();
var options = {
header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,
knownLength: 1
};
form.append('my_buffer', buffer, options);
form.submit('http://example.com/', function(err, res) {
if (err) throw err;
console.log('Done');
});
在上面的示例中,创建了一个FormData()
对象,数据被附加到表单,然后表单被提交。此外,还有一个自定义的hedear。
我将我提出的代码与上面提供的代码中的代码合并,得到了解决我问题的代码:
var formData = require('form-data');
var fs = require('fs');
var CRLF = '\r\n';
var form = new FormData();
var options = {
header: '--' + form.getBoundary() +
CRLF + 'Content-Disposition: form-data; name="file";'+
'filename="bubbles.wgt"'+
CRLF + 'Content-Type: application/octet-stream' +
CRLF + CRLF
};
form.append('file',fs.readFileSync('./uploads/bubbles.wgt'),options);
form.submit({
host: host,
port: '8080',
path: '/wookie/widgets',
auth: 'java:java'
}, function(err, res) {
if (err) throw err;
console.log('Done');
console.log(res);
});
我希望对其他人有所帮助。
干杯, 米甲