首页 > 解决方案 > 如何将整个图像传递给下一个 JS 中的 api 路由,以便我可以用 FS 编写它并用 cloudinary 发送

问题描述

我有以下使用反应钩子形式的形式。

我应该通过 fetch 将什么传递给 API 路由,以便我可以使用 fs 将图像写入磁盘,并检索其位置并将其传递给 Cloudinary?在获取的主体中,我可以传递数据内部的图片对象,但这如何为我提供足够的信息来使用 fs 将图像写入磁盘。

我想将完整的图像路径传递给 Cloudinary,以便它可以上传图像,我目前只传递错误的名称。

<form onSubmit={handleSubmit(onSubmit)}>
    <div>
    <h2>Image</h2>
    <input ref={register} type="file" name="picture" />
    </div>
    <div>
    <h2>Description</h2>
    <input
        type="text"
        placeholder="Description"
        name="description"
        ref={register({ required: true })}
    />
    </div>
    <div>
    <input type="submit" />
    </div>
</form>

这是调用的 onSubmit 函数

const onSubmit = async (data) => {
    console.log(data);
  

    console.log(data);

    const res = await fetch("../api/image", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data.picture[0].name),
    }).then((ok) => {
      console.log(ok);
    });

  };

这是它正在命中的 API 路由

var cloudinary = require("cloudinary").v2;
import { fs } from "fs";

// first we need to disable the default body-parser

cloudinary.config({
  cloud_name: process.env.CLOUDINARY_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET,
});

export default async function image(req, res) {

  cloudinary.uploader.upload(`${req.body}`, function (error, result) {
  console.log(result, error);
  });

  try {
    // const result = req.body;
    res.status(200).send(req.body);
  } catch (error) {
    console.error(error);
    res.status(error.requestResult.statusCode).send(error.message);
  }

这是我可以访问数据对象中的图片对象的内容

对象

更新:我已经尝试过这个问题的建议无济于事,它只是在 form.parse 之后返回 null 和两个空对象。

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

客户

const formData = new FormData();
    formData.append("image", data.picture[0]);

    const res = await fetch("../api/image", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(formData),
    }).then((ok) => {
      console.log(ok);

服务器

var cloudinary = require("cloudinary").v2;
import { fs } from "fs";
import formidable from "formidable";

// first we need to disable the default body parser
export const config = {
  api: {
    bodyParser: false,
  },
};

cloudinary.config({
  cloud_name: process.env.CLOUDINARY_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET,
});

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

  //   cloudinary.uploader.upload(`${body}`, function (error, result) {
  //     console.log(result, error);
  //   });

  try {
    // const result = req.body;
    res.status(200).send(req.body);
  } catch (error) {
    console.error(error);
    res.status(error.requestResult.statusCode).send(error.message);
  }
}

更新:所以如果我执行以下操作,formData 是一个空对象,但控制台日志不是,为什么会这样,我认为这是我的问题。

formData.append("image", data.picture[0]);

    console.log(data.picture[0]);
    console.log(formData); // empty

所以显然你不能只是控制台日志formData,但看起来你可以做到这一点,这就是说文件对象在那里,所以不知道为什么这不起作用。

for (var key of formData.entries()) {
      console.log(key[0] + ", " + key[1]);
    }

标签: javascriptnode.jsformsnext.jscloudinary

解决方案


我认为你在正确的轨道上,但你应该从客户端上传中删除标题,我也不认为你需要stringify它:

const formData = new FormData();
formData.append("image", data.picture[0]);

const res = await fetch("../api/image", {
  method: "POST",
  body: formData,
}).then(ok => {
  console.log(ok);
});

您应该删除标题的原因是(引用mdn 文档):

警告:当使用 FormData 提交使用 XMLHttpRequest 或 Fetch_API 与 multipart/form-data Content-Type 的 POST 请求时(例如,将文件和 Blob 上传到服务器时),不要在请求上显式设置 Content-Type 标头。这样做会阻止浏览器使用边界表达式设置 Content-Type 标头,它将用于分隔请求正文中的表单字段。

您无法控制台记录的原因formData是因为它没有可枚举的键,所以在这种情况下toString()方法console.log是没用的。再次引用 mdn:

可枚举属性出现在 for...in 循环中,除非属性的键是 Symbol

为了记录你的属性,formData你必须这样做:

for (var [key, value] of formData.entries()) {
  console.log(key, value);
}

或查看此线程以获得更多可能性。


推荐阅读