所以我正在尝试将图像从反应前端发送到 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]
您遇到的问题与您尝试上传的图片的 MIME 类型有关。具体来说,图片的文件扩展名为
.jpg
,而其MIME类型为image/jpeg
。当您在后端处理图像时,您使用的是 MIME 类型 jpeg
而不是文件扩展名 .jpg
.
要解决此问题,一种可能的解决方案是避免在后端完全使用 MIME 类型,而是依赖文件扩展名。通过这种方式,您可以确保使用正确的文件类型,并且可以毫无问题地访问图像。
另外重要的是确保在发送图片到客户端时使用正确的MIME类型,以确保它在浏览器中正确显示。
问题是没有
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
}