为什么我的函数在 storage.single 中被调用了两次?
Why is my function called twice in storage.single?
我不知道为什么我的函数在 storage.single
.
中被调用了两次
app.post("/upload-file", async (req, res, next) => {
try {
export const inMemoryStorage = (opts = {}) => {
return multer({ storage: multer.memoryStorage(), ...defaultOpts,
...opts })
}
const storage = inMemoryStorage();
storage.single('file')(req, res, () => {
console.log(req.file) // in my last update
console.log('called') // this is returned two times
return this.uploadService.uploadFile(req)
})
} catch (err) {
next(err);
}
});
}
如有解决方案,谢谢。我只希望我的函数被调用一次。
---- 新编辑----
所以我的上传服务是这样的:
async uploadFile(req) {
const b2 = new B2({
applicationKeyId: 'private1',
applicationKey: 'private2'
})
const upload = await b2.getUploadUrl({ bucketId: 'my-private-key' })
const myfile = await b2.uploadFile({
uploadUrl: upload.data.uploadUrl,
uploadAuthToken: upload.data.authorizationToken,
fileName: getFilename(req.file),
data: req.file.buffer,
onUploadProgress: (event) => null
})
console.log(myfile) // it works
return myfile
}
所以我的上传成功了,我可以看到我的 console.log。所以在我的数据库中,比如第一次上传后 15 秒,另一个文件从我的方法和我的 console.log return 我两次 objets
------------ 最后更新----------
我注意到一些事情,我不知道为什么,但是当我的文件大于 50mb 时。我的函数被调用了 2 次。在 50mb 以下,一切都是正确的,我只发送了一次我的文件
如您所见,我添加了 console.log(req.file)。结果是:
{
fieldname: 'file',
originalname: 'myMovie.mp4',
encoding: '7bit',
mimetype: 'video/mp4',
buffer: <Buffer 1a 45 df a3 01 00 00 00 00 00 00 23 42 86 81 01 42 f7 81 01 42 f2 81 04 42 f3 81 08 42 82 88 6d 61 74 72 6f 73 6b 61 42 87 81 04 42 85 81 02 18 53 80 ... 107390076 more bytes>,
size: 107390126
}
{
fieldname: 'file',
originalname: 'myMovie.mp4',
encoding: '7bit',
mimetype: 'video/mp4',
buffer: <Buffer 1a 45 df a3 01 00 00 00 00 00 00 23 42 86 81 01 42 f7 81 01 42 f2 81 04 42 f3 81 08 42 82 88 6d 61 74 72 6f 73 6b 61 42 87 81 04 42 85 81 02 18 53 80 ... 107390076 more bytes>,
size: 107390126
}
所以我的两个req.file是一样的
连同调试消息 called
尝试添加以下内容。
console.log(new Error().stack);
这将帮助您确定 redundant/duplicate 呼叫的来源。
首先,uploadFile 是一个异步函数,所以storage.single代码应该像
storage.single('file')(req, res, async () => {
console.log('called')
return await this.uploadService.uploadFile(req)
})
此外,如果回调向您发回错误怎么办?
storage.single('file')(req, res, async (err) => {
if (err) {
// handle err
}
console.log('called')
return await this.uploadService.uploadFile(req)
})
现在,我不确定你是如何在 api 中使用它的。
根据我之前处理文件上传的方式,
function fileParser(req, res, opts = {}) {
return new Promise((resolve, reject) => {
multer({ storage: multer.memoryStorage(), ...defaultOpts, ...opts })
.single("file")(req, res, (err) => {
if (err) {
return reject(err);
}
return resolve();
});
});
}
async function fetchAndUploadFile(req, res, opts = {}) {
await fileParser(req, res, opts);
await uploadService.uploadFile(req);
}
// usage in api route
app.post("/your-route", async (req, res, next) => {
try {
await fetchAndUploadFile(req, res);
// other api logic & return response
} catch (err) {
next(err);
}
});
试试这个,如果有帮助请告诉我。另外,您使用的是 express 还是其他框架,例如 feathers? (问是因为我在使用羽毛框架时看到过类似的查询)
我想我在您更新的代码示例中看到了问题。您没有在 upload-file
路由处理程序中将响应发送回客户端,这导致浏览器重新发送请求。
修改handler如下
app.post("/upload-file", async (req, res, next) => {
try {
export const inMemoryStorage = (opts = {}) => {
return multer({ storage: multer.memoryStorage(), ...defaultOpts,
...opts })
}
const storage = inMemoryStorage();
storage.single('file')(req, res, () => {
console.log(req.file) // in my last update
console.log('called') // this is returned two times
await this.uploadService.uploadFile(req);
res.sendStatus(200); // or equivalent
})
} catch (err) {
next(err);
}
});
}
我不知道为什么我的函数在 storage.single
.
app.post("/upload-file", async (req, res, next) => {
try {
export const inMemoryStorage = (opts = {}) => {
return multer({ storage: multer.memoryStorage(), ...defaultOpts,
...opts })
}
const storage = inMemoryStorage();
storage.single('file')(req, res, () => {
console.log(req.file) // in my last update
console.log('called') // this is returned two times
return this.uploadService.uploadFile(req)
})
} catch (err) {
next(err);
}
});
}
如有解决方案,谢谢。我只希望我的函数被调用一次。
---- 新编辑----
所以我的上传服务是这样的:
async uploadFile(req) {
const b2 = new B2({
applicationKeyId: 'private1',
applicationKey: 'private2'
})
const upload = await b2.getUploadUrl({ bucketId: 'my-private-key' })
const myfile = await b2.uploadFile({
uploadUrl: upload.data.uploadUrl,
uploadAuthToken: upload.data.authorizationToken,
fileName: getFilename(req.file),
data: req.file.buffer,
onUploadProgress: (event) => null
})
console.log(myfile) // it works
return myfile
}
所以我的上传成功了,我可以看到我的 console.log。所以在我的数据库中,比如第一次上传后 15 秒,另一个文件从我的方法和我的 console.log return 我两次 objets
------------ 最后更新----------
我注意到一些事情,我不知道为什么,但是当我的文件大于 50mb 时。我的函数被调用了 2 次。在 50mb 以下,一切都是正确的,我只发送了一次我的文件
如您所见,我添加了 console.log(req.file)。结果是:
{
fieldname: 'file',
originalname: 'myMovie.mp4',
encoding: '7bit',
mimetype: 'video/mp4',
buffer: <Buffer 1a 45 df a3 01 00 00 00 00 00 00 23 42 86 81 01 42 f7 81 01 42 f2 81 04 42 f3 81 08 42 82 88 6d 61 74 72 6f 73 6b 61 42 87 81 04 42 85 81 02 18 53 80 ... 107390076 more bytes>,
size: 107390126
}
{
fieldname: 'file',
originalname: 'myMovie.mp4',
encoding: '7bit',
mimetype: 'video/mp4',
buffer: <Buffer 1a 45 df a3 01 00 00 00 00 00 00 23 42 86 81 01 42 f7 81 01 42 f2 81 04 42 f3 81 08 42 82 88 6d 61 74 72 6f 73 6b 61 42 87 81 04 42 85 81 02 18 53 80 ... 107390076 more bytes>,
size: 107390126
}
所以我的两个req.file是一样的
连同调试消息 called
尝试添加以下内容。
console.log(new Error().stack);
这将帮助您确定 redundant/duplicate 呼叫的来源。
首先,uploadFile 是一个异步函数,所以storage.single代码应该像
storage.single('file')(req, res, async () => {
console.log('called')
return await this.uploadService.uploadFile(req)
})
此外,如果回调向您发回错误怎么办?
storage.single('file')(req, res, async (err) => {
if (err) {
// handle err
}
console.log('called')
return await this.uploadService.uploadFile(req)
})
现在,我不确定你是如何在 api 中使用它的。
根据我之前处理文件上传的方式,
function fileParser(req, res, opts = {}) {
return new Promise((resolve, reject) => {
multer({ storage: multer.memoryStorage(), ...defaultOpts, ...opts })
.single("file")(req, res, (err) => {
if (err) {
return reject(err);
}
return resolve();
});
});
}
async function fetchAndUploadFile(req, res, opts = {}) {
await fileParser(req, res, opts);
await uploadService.uploadFile(req);
}
// usage in api route
app.post("/your-route", async (req, res, next) => {
try {
await fetchAndUploadFile(req, res);
// other api logic & return response
} catch (err) {
next(err);
}
});
试试这个,如果有帮助请告诉我。另外,您使用的是 express 还是其他框架,例如 feathers? (问是因为我在使用羽毛框架时看到过类似的查询)
我想我在您更新的代码示例中看到了问题。您没有在 upload-file
路由处理程序中将响应发送回客户端,这导致浏览器重新发送请求。
修改handler如下
app.post("/upload-file", async (req, res, next) => {
try {
export const inMemoryStorage = (opts = {}) => {
return multer({ storage: multer.memoryStorage(), ...defaultOpts,
...opts })
}
const storage = inMemoryStorage();
storage.single('file')(req, res, () => {
console.log(req.file) // in my last update
console.log('called') // this is returned two times
await this.uploadService.uploadFile(req);
res.sendStatus(200); // or equivalent
})
} catch (err) {
next(err);
}
});
}