我创建了一个node.js服务器,它使用busboy接收请求,并将文件通过管道传输到Imgur上传。但是,我不断收到Imgur的"上传文件太快!"的响应,我不确定问题到底是什么。以下是涉及busboy的代码片段:
var express = require('express');
var Busboy = require('busboy');
var fs = require('fs');
var request = require('request-promise');
var router = express.Router();
router.post('/u', function(req, res, next) {
var busboy = new Busboy({headers: req.headers});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
if(fieldname == 'image') {
var options = {
uri: 'https://api.imgur.com/3/image',
method: 'POST',
headers: {
'Authorization': 'Client-ID ' + clientID // put client id here
},
form: {
image: file,
type: 'file'
}
};
request(options)
.then(function(parsedBody) {
console.log(parsedBody);
})
.catch(function(err) {
console.log(err);
});
}
});
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) {
console.log('field');
});
busboy.on('finish', function() {
res.status(200).end();
});
req.pipe(busboy);
});
如您所见,我将请求文件直接管道到我的 imgur 请求中。通过简单地将文件保存到光盘然后使用fs.createReadStream()
来提供 ReadStream 效果很好,所以我不太确定为什么尝试直接从请求到请求进行管道会给我错误。我从Imgur得到的确切回应是:
StatusCodeError: 400 - {"data":{"error":"Uploading file too fast!","request":"/3/image","method":"POST"},"success":false,"status":400}
如果有人以前遇到过这种情况,那将是有帮助的......
第一个问题是您应该使用formData而不是form进行文件上传。否则,请求库将不会发送正确的 HTTP 请求。
第二个问题是,流对象在完全处理之前不会具有正确的内容长度。我们可以自己缓冲数据,并在处理来自 busboy 的初始文件流后传递它。
这给了我们一些看起来像
var express = require('express');
var Busboy = require('busboy');
var fs = require('fs');
var request = require('request-promise');
var router = express.Router();
router.post('/u', function(req, res, next) {
var busboy = new Busboy({headers: req.headers});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
if(fieldname == 'image') {
// the buffer
file.fileRead = [];
file.on('data', function(data) {
// add to the buffer as data comes in
this.fileRead.push(data);
});
file.on('end', function() {
// create a new stream with our buffered data
var finalBuffer = Buffer.concat(this.fileRead);
var options = {
uri: 'https://api.imgur.com/3/image',
method: 'POST',
headers: {
'Authorization': 'Client-ID ' + clientID // put client id here
},
formData: {
image: finalBuffer,
type: 'file'
}
};
request(options)
.then(function(parsedBody) {
console.log(parsedBody);
})
.catch(function(err) {
console.log(err);
});
});
}
});
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) {
console.log('field');
});
busboy.on('finish', function() {
res.status(200).end();
});
req.pipe(busboy);
});
- 缓冲代码来自 http://thau.me/2014/02/nodejs-streaming-files-to-amazons3/
,因为请求-承诺库不鼓励使用流。有关更多详细信息,请参阅 github 存储库:https://github.com/request/request-promise