如何使用 formdata 将图像文件发送到 React/Next js api?
Posted
技术标签:
【中文标题】如何使用 formdata 将图像文件发送到 React/Next js api?【英文标题】:How to send an image file using formdata to React/Next js api? 【发布时间】:2021-02-04 23:25:09 【问题描述】:我正在尝试将文件发送到下一个 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,如上所示?
我认为这个问题也可以问为:为什么使用bodyParser: false
时req.body undefined
?
【问题讨论】:
您的 API 在哪里实现(Next.js 的 API 路由或其他项目/框架)? @nghiaht 它在 nextjs api 路由中。谢谢 【参考方案1】:我遇到了同样的错误,但 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);
);
;
【讨论】:
谢谢。我已经将图像放入表单数据中 -formData.append('postPic', imageUpload.files[0]);
。您能否解释一下在这种情况下强大的功能以及为什么要使用它?
在这种情况下,它用于读取表单数据并提供文件。我得到的东西类似于你想要实现的东西(客户端 -> NextJS -> Express Server -> Cloudinary
告诉我你的进展情况。【参考方案2】:
如果您要上传到 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>);
【讨论】:
也许他想隐藏使用第三服务的秘密 一般来说是的。对于 Cloudinary,不需要隐藏这些参数。在生产中应该做的是使用signed uploads - 意思是在服务器端签署上传数据 @nghiaht - 我认为最好进行签名上传隐藏 api 值。最后,我确实最终直接使用带有 POST 的 cloudinary api url,但它需要上传预设和未签名的上传。 这是一个非常有趣的问题。我正在尝试处理 Next.js 的 API 路由中的多部分表单数据,他们说这是核心 Node.js http 请求,我尝试使用formidable
解析但失败了。如果我能解决它,我会发布一个答案
@Kal 请不要在生产代码中进行未签名的上传。它将允许任何人使用详细信息上传到您的云。签名上传是生产环境中的最佳方式。如果您需要这方面的帮助,请告诉我【参考方案3】:
这对我有用
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
)
);
);
【讨论】:
虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高答案的长期价值。以上是关于如何使用 formdata 将图像文件发送到 React/Next js api?的主要内容,如果未能解决你的问题,请参考以下文章
我可以在javascript中将数组附加到“formdata”吗?
将图像的源(src)添加到 formData 并通过 http post call 将其发布到后端