next.js 文件通过 api 路由上传/强大 - 不工作 [英] next.js file upload via api routes / formidable - not working

查看:19
本文介绍了next.js 文件通过 api 路由上传/强大 - 不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在通过 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆