reactjs 使用NextJS API的FormData

ddarikpa  于 2023-04-11  发布在  React
关注(0)|答案(4)|浏览(282)

我尝试使用NextJS沿着react-redux创建一个简单的CRUD应用程序,所以它所做的就是保存人们的联系人。所以当添加联系人时,我尝试将一些数据和文件一起发送到NextJS API。

问题

ContactAction.js
从redux action发出POST请求以添加联系人

export const addContact = (data) => async (dispatch) => {
 try {
      var formData=new FormData();
      formData.append('name',data.Name);
      formData.append('email',data.Email);
      formData.append('phone',data.Phone);
      formData.append('image',data.Image);
      let response= await Axios.post(`http://localhost:3000/api/contact/addContact`,formData,{
         headers:{
             'x-auth-token':localStorage.getItem('token')
         }
      });
   } catch (error) {
       console.log(error);
   }
}

addContact.js
这是/api/contact/中的API路由

const handler = async (req, res) => {
   switch(req.method){
    case "POST":{
       await addContact(req,res)
       }
     }
   }
   const addContact = async  (req, res) => { 
     console.log(req.body);
    // do some stuff here and send response
   }

这是我在日志后在终端中得到的,在记录req.files时,文件也是Gibberish

目前的努力

我尝试使用第三方软件包,如formidableformidable-serverless,但没有运气。所以一天后,我用一个名为multiparty的软件包使它工作。
addContact.js

const handler = async (req, res) => {
   switch(req.method){
    case "POST":{
      let form = new multiparty.Form();
      let FormResp= await new Promise((resolve,reject)=>{
       form.parse(req,(err,fields,files)=>{
        if(err) reject(err)
        resolve({fields,files})
        });
      }); 
      const {fields,files} = FormResp;
      req.body=fields;
      req.files=files;
       await addContact(req,res)
       }
     }
   }
   const addContact = async  (req, res) => { 
     console.log(req.body); //Now i get an Object which i can use
    // do some stuff here and send response
   }

上面的解决方案显然是多余的,可能不是最好的方式去做它,加上我不想添加这7 8行到每一个路线。
我做错了什么?为什么formData似乎不能与NextJS API一起工作(当它与Express服务器一起工作时)?

s4chpxco

s4chpxco1#

FormData使用multipart/form-data。这不是一个简单的带有主体的POST请求。它通常用于上传文件,这就是为什么它需要特殊处理。作为替代,您可以使用JSON

nnsrf1az

nnsrf1az2#

这是我的解决方案,我希望这对任何人都有帮助。
首先,你需要安装next-connectmulter作为你的依赖。
现在您可以使用此API路由代码。

import nextConnect from "next-connect";
import multer from "multer";

const apiRoute = nextConnect({
  onError(error, req, res) {
    res.status(501).json({ error: `Sorry something Happened! ${error.message}` });
  },
  onNoMatch(req, res) {
    res.status(405).json({ error: `Method "${req.method}" Not Allowed` });
  },
});

apiRoute.use(multer().any());

apiRoute.post((req, res) => {
  console.log(req.files); // Your files here
  console.log(req.body); // Your form data here
  // Any logic with your data here
  res.status(200).json({ data: "success" });
});

export default apiRoute;

export const config = {
  api: {
    bodyParser: false, // Disallow body parsing, consume as stream
  },
};
jjhzyzn0

jjhzyzn03#

这在next-13中工作正常

import { NextRequest, NextResponse } from "next/server";
export async function POST(request: NextRequest, response: NextResponse) {
  console.log(await request.formData())
  return new NextResponse("Thank you")
}

就这么简单!

tez616oj

tez616oj4#

下面是一个使用Next.js上传文件的例子:
https://codesandbox.io/s/thyb0?file=/pages/api/file.js
最重要的代码在pages/api/file.js中

import formidable from "formidable";
import fs from "fs";

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

const post = async (req, res) => {
  const form = new formidable.IncomingForm();
  form.parse(req, async function (err, fields, files) {
    await saveFile(files.file);
    return res.status(201).send("");
  });
};

const saveFile = async (file) => {
  const data = fs.readFileSync(file.path);
  fs.writeFileSync(`./public/${file.name}`, data);
  await fs.unlinkSync(file.path);
  return;
};

一般来说,在您的API文件中,您应该禁用默认的bodyParser,并编写您自己的解析器

相关问题