Node.js Busboy 未在 "finish" 事件之前触发 "file" 事件
Node.js Busboy not firing "file" event before "finish" event
我只是想通过 Node.js/Next.js 从浏览器上传文件到 S3,而 busboy 没有发出 file
事件。
这是我的 FE 代码:
Upload.prototype.to = function(options, fn){
// TODO: x-browser
var path;
if (typeof options == 'string') {
path = options;
options = {};
} else {
path = options.path;
}
var self = this;
fn = fn || function(){};
var req = this.req = new XMLHttpRequest;
req.open('POST', path);
req.onload = this.onload.bind(this);
req.onerror = this.onerror.bind(this);
req.upload.onprogress = this.onprogress.bind(this);
req.onreadystatechange = function(){
if (4 == req.readyState) {
var type = req.status / 100 | 0;
if (2 == type) return fn(null, req);
var err = new Error(req.statusText + ': ' + req.response);
err.status = req.status;
fn(err);
}
};
var key, headers = options.headers || {};
for (key in headers) {
req.setRequestHeader(key, headers[key]);
}
var body = new FormData;
body.append(options.name || 'file', this.file);
var data = options.data || {};
for (key in data) {
body.append(key, data[key]);
}
req.send(body);
};
所做的就是使用 file
名称向 /api/<path>
发出我要上传的选定 jpeg 的请求。这是我在服务器请求中收到的 body:
body: '------WebKitFormBoundaryWbaXO8J6c8aI7Q4B\r\n' +
'Content-Disposition: form-data; name="file"; filename="1-profile.jpg"\r\n' +
'Content-Type: image/jpeg\r\n' +
'\r\n' +
'����\x00\x10JFIF...
headers包括这些:
connection: 'keep-alive',
'content-length': '41079',
pragma: 'no-cache',
'cache-control': 'no-cache',
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryWbaXO87Kc9aI2Q4B',
accept: '*/*',
origin: 'http://localhost:3000',
我的服务器代码如下所示:
import fetchId from '../../../../utils/get-next-id-from-pg'
import Busboy from 'busboy'
import s3 from 'initializers/s3'
export default async function(req, res) {
if (req.method === 'POST') {
const id = await fetchId('image')
return new Promise((resolve, rej) => {
const busboy = new Busboy({ headers: req.headers });
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
})
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
console.log('params')
const params = {
Bucket: 'mybucket123',
Key: id,
Body: file
}
s3.upload(params, (err, data) => {
console.log('s3', err, data)
res.setHeader('Connection', 'close');
res.status(200).json({ records: [ { id } ]})
resolve()
})
})
busboy.on('finish', function() {
console.log('finish')
})
req.pipe(busboy);
})
} else {
res.writeHead(405, { 'content-type': 'text/plain' });
res.end("Method not allowed. Send a POST request.");
return;
}
}
它记录 finish
,仅此而已,它不记录 file
或 field
。我在这里错过了什么?它不会在 on('file')
处理程序或任何 s3 内容中记录 params
。我开始深入研究 busboy 源代码,但有没有更好的方法?我做错了什么,或者与 Next.js 一起使用的库是什么?
我正在使用 Next.js 和 dotenv,这会导致奇怪的问题吗?
万岁,我 ,将此添加到 Next.js 路线:
export const config = {
api: {
bodyParser: false,
},
}
https://nextjs.org/docs/api-routes/api-middlewares#custom-config
我只是想通过 Node.js/Next.js 从浏览器上传文件到 S3,而 busboy 没有发出 file
事件。
这是我的 FE 代码:
Upload.prototype.to = function(options, fn){
// TODO: x-browser
var path;
if (typeof options == 'string') {
path = options;
options = {};
} else {
path = options.path;
}
var self = this;
fn = fn || function(){};
var req = this.req = new XMLHttpRequest;
req.open('POST', path);
req.onload = this.onload.bind(this);
req.onerror = this.onerror.bind(this);
req.upload.onprogress = this.onprogress.bind(this);
req.onreadystatechange = function(){
if (4 == req.readyState) {
var type = req.status / 100 | 0;
if (2 == type) return fn(null, req);
var err = new Error(req.statusText + ': ' + req.response);
err.status = req.status;
fn(err);
}
};
var key, headers = options.headers || {};
for (key in headers) {
req.setRequestHeader(key, headers[key]);
}
var body = new FormData;
body.append(options.name || 'file', this.file);
var data = options.data || {};
for (key in data) {
body.append(key, data[key]);
}
req.send(body);
};
所做的就是使用 file
名称向 /api/<path>
发出我要上传的选定 jpeg 的请求。这是我在服务器请求中收到的 body:
body: '------WebKitFormBoundaryWbaXO8J6c8aI7Q4B\r\n' +
'Content-Disposition: form-data; name="file"; filename="1-profile.jpg"\r\n' +
'Content-Type: image/jpeg\r\n' +
'\r\n' +
'����\x00\x10JFIF...
headers包括这些:
connection: 'keep-alive',
'content-length': '41079',
pragma: 'no-cache',
'cache-control': 'no-cache',
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryWbaXO87Kc9aI2Q4B',
accept: '*/*',
origin: 'http://localhost:3000',
我的服务器代码如下所示:
import fetchId from '../../../../utils/get-next-id-from-pg'
import Busboy from 'busboy'
import s3 from 'initializers/s3'
export default async function(req, res) {
if (req.method === 'POST') {
const id = await fetchId('image')
return new Promise((resolve, rej) => {
const busboy = new Busboy({ headers: req.headers });
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
})
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
console.log('params')
const params = {
Bucket: 'mybucket123',
Key: id,
Body: file
}
s3.upload(params, (err, data) => {
console.log('s3', err, data)
res.setHeader('Connection', 'close');
res.status(200).json({ records: [ { id } ]})
resolve()
})
})
busboy.on('finish', function() {
console.log('finish')
})
req.pipe(busboy);
})
} else {
res.writeHead(405, { 'content-type': 'text/plain' });
res.end("Method not allowed. Send a POST request.");
return;
}
}
它记录 finish
,仅此而已,它不记录 file
或 field
。我在这里错过了什么?它不会在 on('file')
处理程序或任何 s3 内容中记录 params
。我开始深入研究 busboy 源代码,但有没有更好的方法?我做错了什么,或者与 Next.js 一起使用的库是什么?
我正在使用 Next.js 和 dotenv,这会导致奇怪的问题吗?
万岁,我
export const config = {
api: {
bodyParser: false,
},
}
https://nextjs.org/docs/api-routes/api-middlewares#custom-config