如何解决 axios 将 jpeg 而不是 jpg 发送到后端的问题?

问题描述 投票:0回答:2

所以我正在尝试将图像从反应前端发送到 node.js 后端,但是当我将 .jpg 发送到后端时,我问它是什么 tpye 说它是 jpeg,而 multer 仍然认为它一个 jpg 所以我在它上面做的尖锐的功能不再工作并给出错误,因为他们找不到文件。

我尝试在我需要文件类型的两个实例中使用(multer 保存它的地方和我声明 sharp 的输入的地方)但是那没有用。这是前端的代码:

function App() {
  const [image, setImage] = useState("");
  function handleImage(e) {
    console.log(e.target.files);
    setImage(e.target.files[0]);
  }
  function handleApi() {
    const formData = new FormData();
    formData.append("image", image);
    formData.append("pfp", "yes");
    formData.append("filetype", image.type )
    console.log('hello')
    console.log(image)
    console.log(formData)
    axios
      .post("http://localhost:3001/users/editprofile/1", formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
      })
      .then((res) => {
        console.log(res);
      });
  }
  return (
    <div>
      <input type="file" name="file" onChange={handleImage} />
      <button onClick={handleApi}>submit</button>
    </div>
  );
}`

这是后端代码:

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "images/temp");
  },
  filename: function (req, file, cb) {
    const id = req.params.id;
    let extention = path.extname(file.originalname);
    cb(null, `pfp_${id}` + extention);
  },
});

router.post("/editprofile/:id", upload.single("image"), async (req, res) => {
  const id = req.params.id;
  const { pfp, bio, filetype } = req.body;
  console.log(bio);
  console.log(req.body);
  if (pfp) {
    const typetemp = filetype.split("/");
    const type = typetemp[typetemp.length - 1];

    var imput = path.join(
      __dirname,
      "..",
      "images/temp",
      "pfp_" + id + "." + type
    );
    var output = path.join(__dirname, "..", "images/temp", id + "png.png");
    var newimage = path.join(
      __dirname,
      "..",
      "images/profile_pictures",
      "pfp_" + id + ".png"
    );

    try {
      const metadata = await sharp(imput).metadata();
      if (metadata.format != "png") {
        await sharp(imput).toFormat("png", { palette: true }).toFile(output);
      } else {
        await sharp(imput).toFile(output);
      }
      if (metadata.height > metadata.width) {
        var topcut = Math.round((metadata.height - metadata.width) / 2);
        await sharp(imput)
          .extract({
            width: metadata.width,
            height: metadata.width,
            left: 0,
            top: topcut,
          })
          .toFile(newimage);
      } else if (metadata.height < metadata.width) {
        var leftcut = Math.round((metadata.width - metadata.height) / 2);
        console.log(leftcut);
        await sharp(imput)
          .extract({
            width: metadata.height,
            height: metadata.height,
            left: leftcut,
            top: 0,
          })
          .toFile(newimage);
      }
      const metadatanew = await sharp(newimage).metadata();
      console.log(metadatanew);
      var newpfp = id + ".png";
    } catch (error) {
      console.log(error);
    }
  }

当我尝试上传 jpg 时,控制台出现以下错误:

[Object: null prototype] { pfp: 'yes', filetype: 'image/jpeg' }
[Error: Input file is missing: D:\programmeerstuff\javascript\pws\version 0.0.1\server\images\temp\pfp_1.jpeg]

这是我尝试上传的图片:(不要介意上面有什么,这只是我点击选择文件 XD 时看到的第一张图片)

node.js reactjs axios multer
2个回答
1
投票

您遇到的问题与您尝试上传的图片的 MIME 类型有关。具体来说,图片的文件扩展名为

.jpg
,而其MIME类型为
image/jpeg
。当您在后端处理图像时,您使用的是 MIME 类型
jpeg
而不是文件扩展名
.jpg
.

要解决此问题,一种可能的解决方案是避免在后端完全使用 MIME 类型,而是依赖文件扩展名。通过这种方式,您可以确保使用正确的文件类型,并且可以毫无问题地访问图像。

另外重要的是确保在发送图片到客户端时使用正确的MIME类型,以确保它在浏览器中正确显示。


-1
投票

问题是没有

image/jpg
mime 类型,而您正在使用 mime 类型创建文件扩展名,它始终是
image/jpeg
,所以您总是以
.jpeg
文件扩展名结束。

解决方案是从前端发送文件扩展名,而不是 mime 类型:

// get file extension, maybe also add extra check to ensure there is one   
const filetype = image.name.split('.').pop();

formData.append("filetype", filetype )

快速而肮脏的解决方案是检查文件是否存在(并在需要时添加额外的检查)。

试试这个,在服务器上添加,在那里你设置

type
imput
(不需要设置
type
,现在
fileType
包含来自前端的扩展:

const fs = require('fs');

let imput = path.join(
          __dirname,
          "..",
          "images/temp",
          "pfp_" + id + "." + filetype
        );


if(!fs.existsSync(imput)) {

        
        // no file, return error


}
© www.soinside.com 2019 - 2024. All rights reserved.