Я пытаюсь загрузить изображение с помощью multer, следуя руководству YouTube. Но не в состоянии понять, почему он не работает должным образом.
Код:
Index.html
<body>
<form method = "post" action = "/upload" enctype = "multipart/form-data">
<input type = "file" name = "image">
<input type = "submit">
</form>
</body>
Сервер.js
const path = require('path');
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
app.use(express.static(path.join(__dirname,"../public")));
const multer=require('multer');
const storage=multer.diskStorage({
destination:(req,file,cb)=>{
cb(null,"./Images")
},
filename: (req,file,cb)=>{
console.info(file)
cb(path.extname(file.originalname));
console.info("---")
}
});
const upload=multer({storage:storage});
app.post("/upload",upload.single('image'),(req,res)=>{
console.info("up")
});
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname,'../public/index.html'));
});
server.listen(3000, () => {
console.info('listening on *:3000');
});
Журналы:
listening on *:3000
{
fieldname: 'image',
originalname: 'vidLogo.jpg',
encoding: '7bit',
mimetype: 'image/jpeg'
}
---
Как видите, логи генерируются до конца.
Сервер выдает внутреннюю ошибку сервера (500) и отправляет файл ответа, как показано ниже:
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<title>Error</title>
</head>
<body>
<pre>.jpg</pre>
</body>
</html>
${process.cwd()}/Изображения/`)
Добавить параметр ошибки в функцию обратного вызова: cb (ошибка может быть нулевой)
const storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, `${process.cwd()}/Images/`); // destination
},
filename(req, file, cb) {
cb(
null,
`${file.fieldname}-${Date.now()}${path.extname(file.originalname)}` // filename
);
},
});
Полный пример с расширенными проверками путем загрузки файлов
import path from "path";
import express from "express";
import multer from "multer";
import asyncHandler from "express-async-handler";
import process from "process";
const router = express.Router();
const storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, `${process.cwd()}/uploads/documents/`);
},
filename(req, file, cb) {
cb(
null,
`${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`
);
},
});
function checkFileType(file, cb) {
const extensionsAutorisees = [
"text/plain",
"application/pdf",
];
if (extensionsAutorisees.includes(file.mimetype)) {
return cb(null, true);
} else {
return cb(
new Error(`Only documents of type PDF, Text are authorized`)
);
}
}
const upload = multer({
storage,
limits: {
fileSize: 1024 * 1024 * 5, // 5Mb file size limit
},
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
},
}).single("document");
router.route("/").post(
protect,
asyncHandler(async (req, res) => {
upload(req, res, async (err) => {
if (
err &&
err.name &&
err.name === "MulterError" &&
err.code == "LIMIT_FILE_SIZE"
) {
return res.status(400).send({
error: err.name,
message: `Document too large, the maximum size is 5Mb`,
});
}
// handle other errors
if (err) {
return res.status(500).send({
error: "FILE UPLOAD ERROR",
message: `Document loading error : ${err.message}`,
});
}
return res.status(201);
});
})
);
Если использовать этот код: «${path.extname(file.originalname)}», вы извлекаете только расширение «.jpg» (ссылка: w3schools.com/nodejs/…) // используйте originalname => const storage = multer.diskStorage({ ... имя_файла(req, file, cb) { cb(null, ${file.originalname}); }, }); // или пользовательский, ссылаясь на мой пример с форматом даты в ответе
Ошибка находится во втором обратном вызове внутри функции filename, где вам нужно указать null как ошибку и имя файла как значение: cb(null, path.extname(file.originalname));
Попробуйте обновить свой код следующим образом:
const storage=multer.diskStorage({
destination:(req,file,cb)=>{
cb(null,"./Images")
},
filename: (req,file,cb)=>{
console.info(file)
// I updated the file name as well so that it is not extension only
cb(null, file.fieldname + path.extname(file.originalname)); // <--- HERE
console.info("---")
}
});
Я внес изменения, предложенные вами ранее, но создал новый файл с именем '.jpg' , внутри которого ничего нет.