如何使用 formdata 将图像文件发送到 React/Next js api?

IT技术 reactjs next.js vercel
2021-05-08 19:21:42

我正在尝试在下一个 js 应用程序中将文件发送到 api。图像将上传到 cloudinary:

函数调用api是:

  async uploadButtonClicked(imageUpload) {
      const formData = new FormData();
      //formData.append('test', "testing");
      formData.append('postPic', imageUpload.files[0]);
      const res = await fetch('/api/hello', {
        method: 'POST',
        headers: {
          'Content-Type': 'multipart/form-data',
          'Accept': 'application/json'
        },
        body: formData,
      })

console.log(imageUpload.files[0]) 在前端给了我下面的值,看起来不错。 在此处输入图片说明

在 API 中,

export default (upload.single('postPic'), async (req, res) => {
  console.log(req.body)

以上是undefined我使用时

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

当我删除 bodyParser 设置(bodyParser 为 true)时,数据是一个对上传没有用的流。我收到上传错误,如下所示: 在此处输入图片说明

如果正文以以下格式到达 api,Cloudinary 将上传: 在此处输入图片说明

应该更改什么才能使主体(基本上是图像文件)以正确的格式到达 api,如上所示?

我认为这个问题也可以问为:为什么req.body undefined使用时bodyParser: false

3个回答

我遇到了同样的错误,但 Formidable 对我有用。首先尝试将图像放入表单数据中。

来自客户:

export const uploadImage = async (image) => {

    const formData = new FormData();
    formData.append('image', image);
    const response = await axios.post('/api/v1/image', formData);
    return response.data;
}

以下是服务器 API:/api/v1/image

import formidable from 'formidable';


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

export default async (req, res) => {
  const form = new formidable.IncomingForm();
  form.uploadDir = "./";
  form.keepExtensions = true;
  form.parse(req, (err, fields, files) => {
    console.log(err, fields, files);
  });
};

如果您要上传到 Cloudinary,为什么要尝试将文件从客户端发送到您的 nextjs api?您可以直接上传到 Cloudinary。

使用像react-uploady这样的库就这么简单:

import React from "react";
import Uploady from "@rpldy/uploady";
import UploadButton from "@rpldy/upload-button";

const CLOUD_NAME = "<your-cloud-name>";
const UPLOAD_PRESET = "<your-upload-preset>";

const App = () => (<Uploady
    destination={{ 
        url: `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/upload`,
        params: {
            upload_preset: UPLOAD_PRESET,
        }
    }}>
    <UploadButton/>
</Uploady>);

这对我有用

import cloudinary from 'cloudinary';
import formidable from 'formidable';

cloudinary.config({ 
  cloud_name: '', 
  api_key: '', 
  api_secret: '' 
});

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

export default async (req, res) => {
  const form = new formidable.IncomingForm();
  form.uploadDir = "./";
  form.keepExtensions = true;
  await form.parse(req, (err, fields, files) => {
    cloudinary.v2.uploader.upload(files.image.path, function(error, result) {
      res.status(200).json({
        success: true,
        data: result.secure_url
      })
    });
  });
}