【问题标题】:next.js file upload via api routes / formidable - not workingnext.js 文件通过 api 路由上传/强大 - 不工作
【发布时间】:2020-02-01 19:07:20
【问题描述】:

我在通过 api 路由上传文件时遇到了麻烦。

在客户端即时提交文件,如下所示:

 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)
 }

我对@9​​87654323@ 的请求如下所示:

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)中我尝试使用强大的来解析表单数据,最后对文件做一些事情。

我确保通过在 api 路由文件的底部包含以下内容来禁用内置的正文解析器:

export const config = {
  api: {
    bodyParser: false
  }
}

^^ 这才是正确的做法,对吧?

最后,在 api 路由中,我尝试了很多不同的东西,但目前以下是我期望的工作,但它不是..

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) 在服务器端输出文件名等。

有人知道我错过了什么吗?

【问题讨论】:

  • 万一有人遇到这个问题并有类似的问题 - 我最终没有弄清楚这个确切的问题,但我通过使用 cloudinaries 免费服务解决了这个问题(大约 25gb ~ 一个月,如果你'只是在没有任何转换等的情况下进行基本的文件上传)使用他们在 codepen 上的示例(简单的 xhr 上传):codepen.io/team/Cloudinary/pen/QgpyOK

标签: reactjs file-upload next.js formidable


【解决方案1】:

【讨论】:

  • 是的,这确实有效。
【解决方案2】:

我 100% 确定您的问题是由混合 CommonJS 导出(即module.exports = )和 ES6 模块语法(export const config = ...)引起的。

当您执行此操作时,NextJS 只会看到默认导出并且看不到您的配置声明,因此会继续解析正文。反过来,这会导致 req 在传递给 formidable 时已经完成。

除此之外,您的代码中的一切看起来都正确。只需改变

module.exports = async (req, res) => {

export default async (req, res) => {

你应该得到预期的行为。

【讨论】:

    【解决方案3】:

    我相信,如果您在端点内部执行异步操作,那么 next.js 期望您返回一个承诺,例如

    export default (req, res) => {
     const promise = new Promise((resolve, reject) => {
    
      const form = new formidable.IncomingForm();
    
      form.parse(req, (err, fields, files) => {
        if (err) reject(err);
        resolve({fields, files});
      })
    
     })
    
     return promise.then(({fields, files}) => {
        res.status(200).json({ fields, files })
     })
    }
    

    【讨论】:

      【解决方案4】:

      您可以通过如下所述的简单方式实现它->

      以简单的方式从客户端发送文件将是 ->

      客户端->

      const file = e.target.files[0];
      const formData = new FormData();
      formData.append("file", file);
      
      const { data } = await axios.post("/api/upload",formData)
      

      在后端安装 express-formidable

      后端 api 将是 ->

      import express from 'express';
      import expressAsyncHandler from 'express-async-handler';
      import formidable from 'express-formidable';
      
      const router = express.Router();
      export const config = {
          api: {
             bodyParser: false,
          },
      };
           
      export default router.post('/upload',formidable() ,expressAsyncHandler(async (req, res) => {
          const {file} = req.files;
          console.log(file);
          // here you can handle the incoming file to send it to cloud
            
      }));
      

      express-formidable 将处理所有传入的流并通过将所有数据存储到“数据”变量来为我们提供数据。为了将其存储到任何云(aws s3,cloudinary),创建一个可读流并将其附加到表单数据中,然后发送它。

      【讨论】:

      • 如何在 ES6 的 module.exports 中使用 bodyParser ?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 2020-05-19
      • 2021-09-30
      • 1970-01-01
      • 2016-07-29
      • 2018-09-01
      • 1970-01-01
      相关资源
      最近更新 更多