next.js 文件通过 api 路由上传/强大 - 不工作 [英] next.js file upload via api routes / formidable - not working
问题描述
我在通过 api 路由上传文件时遇到了麻烦.
I'm having a hell of a time getting file upload to work via api routes.
在客户端即时提交文件,如下所示:
On client-side im submitting the file like so:
onFormSubmit = (e) => {
e.preventDefault() // Stop form submit
this.fileUpload(this.state.file).then((response) => {
console.log('rD', response.data)
})
}
onFileChange = (e) => {
this.setState({ file: e.target.files[0] })
}
fileUpload = (file) => {
const url = '/api/mail/upload'
const formData = new FormData()
formData.append('file', file)
const config = {
headers: {
'X-CSRF-TOKEN': this.props.session.csrfToken
}
}
return axios.post(url, formData, config)
}
我对 /api/mail/upload
的请求如下所示:
My request to /api/mail/upload
then looks like this:
Request Headers:
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,de-DE;q=0.8,de;q=0.7
Connection: keep-alive
Content-Length: 1331
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBlNt6z8t4rGZT0x6
Cookie: abc123
Host: localhost:3000
Origin: http://localhost:3000
Referer: http://localhost:3000/new
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36
X-CSRF-TOKEN: abc123
Form Data:
file: (binary)
然后在路由(/api/mail/upload)我尝试使用强大的来解析表单数据,最后对文件做一些事情.
Then in the route (/api/mail/upload) I'm trying to use formidable to parse the form data and finally do something with the file.
我已确保通过在 api 路由文件底部包含以下内容来禁用内置的正文解析器:
I've made sure to disable the built-in body parser by including the following at the bottom of the api route file:
export const config = {
api: {
bodyParser: false
}
}
^^ 这才是正确的做法,对吧?
^^ Thats the correct way to do that, right?
最后,在 api 路由中,我尝试了很多不同的东西,但目前以下是我期望的工作,但它不是..
Finally, in the api route, I've tried many different things, but currently the following is what I expect to work, but it is not..
module.exports = async (req, res) => {
const form = new formidable.IncomingForm()
form.parse(req, (err, fields, files) => {
if (err) return reject(err)
console.log(fields, files)
res.status(200).json({ fields, files })
})
// if I console.log(form) here - I can see the request details, so it seems to be picking that up
}
这不会在服务器端或客户端生成任何输出,我希望 console.log(fields, files)
在服务器端输出文件名,等等
This generates no output whatsoever on the server-side nor on client-side, i expect the console.log(fields, files)
to output on the server-side the name of the file, etc.
有人知道我错过了什么吗?
Anyone know what I am missing?
推荐答案
我 100% 确定您的问题是由混合 CommonJS 导出(即 module.exports =
)和 ES6 模块语法(export const config = ...
).
I am 100% sure your issue is caused by intermixing CommonJS exports (i.e. module.exports =
) and ES6 modules syntax (export const config = ...
).
当您执行此操作时,NextJS 只会看到默认导出并且看不到您的配置声明,因此会继续解析正文.反过来,这会导致 req
在传递给 formidable
时已经完成.
When you do this NextJS sees only default export and doesn't see your config declaration and hence continues to parse body. Which, in turn, results in req
to be already completed by the time it's being passed to formidable
.
除此之外,您的代码中的一切看起来都正确.只需改变
Apart from that everything looks right in your code. By just changing
module.exports = async (req, res) => {
到
export default async (req, res) => {
你应该得到预期的行为.
you should get an expected behaviour.
这篇关于next.js 文件通过 api 路由上传/强大 - 不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!