Giriş
Hepinize Merhabalar👋
Bu yazımızda, nodejs altyapılı bir projemize nasıl görsel veya başka bir dosyayı yükleyip, sunucuda bir kopyasını tutacağımızı inceleyeğiz.
Bu işlemleri yaparken de dosya yükleme işlemlerini kolaylaştıran multer kütüphanesinden yardım alacağız. Hazırsanız başlayalım.
Front-end'in yazılması
Öncelikle HTML
tarafında dosyayı almak için bir input ve sunucuya isteği tetiklemek için bir button ekleyelim;
<body>
<input id="file" type="file" />
<button id="upload">Submit</button>
</body>
Şimdi de butona tıkladıktan sonra çalışacak kodları yazalım;
<script>
document.querySelector("#upload").addEventListener("click", async () => {
const fileInput = document.querySelector("#file");
const formData = new FormData();
for (let i = 0; i < fileInput.files.length; i++) {
const file = fileInput.files[i];
formData.append("files", file);
}
let response = await fetch("/upload-file", {
method: "POST",
body: formData,
});
response = await response.json();
console.log(response);
});
</script>
Back-end'in Yazılması
- End-point'in Eklenmesi
Projemizeupload-file
adında,POST
metoduna sahip bir route tanımlayalım.
router.post("/upload-file", (req, res, next) => {});
Gelen isteğe bir yanıt dönelim ve front-end
'de o istekten gelen yanıtı kontrol edelim. Böylelikle butona tıklanıldığı zaman - dosya yüklenilmeden önce - herşeyin çalıştığına emin olacağız.
router.post("/upload-file", (req, res, next) => {
res.json({ message: "upload-file is triggered" });
});
Şuana kadar herşey güzel gözüküyor🎉
Şimdi de projemize multeri entegre ederek, gelen datayı bir klasörün içerisine kaydedelim.
- Multer'in Projeye Dahil Edilmesi
npm i multer --save
komutunu kullanarak kütüphaneyi, projemize indiriyoruz. Route'yi tanımladığımız dosyanın en üstüne gidiyoruz ve multer konfigürasyonlarını yapıyoruz.
const multer = require("multer");
const storage = multer.diskStorage({
destination: (req, file, cb) =>{
cb(null, "uploads");
},
filename: (req, file, cb) =>{
cb(null, file.originalname);
},
});
const upload = multer({ storage }).array("files");
destination:
Gelen dosyanın yükleneceği yolun yapılandırıldığı fonksiyon.
filename:
Gelen dosyanın isminin yapılandırıldığı fonksiyon.
Bunları yaptıktan sonra route
'mizi aşağıdaki şekilde güncelliyoruz.
router.post("/upload-file", (req, res, next) => {
console.log(req.files);
});
Örnek bir dosya yükleyip gelen req.files
objesine bakalım.
storage
kısmında tanımladığımız filename
fonksiyonu, yukarıda bulunan originalname
kısmındaki değeri alarak, kullanıcının yüklediği dosya ismini sunucuya klonlanacak dosyanın ismiyle eşitliyor ve böylelikle uploads
klasörü altında kullanıcının yüklediği dosya klonlanmış oluyor.
Şimdi de upload işlemini yapalım ve hataları yakalamak içinde try/catch
kullanalım.
router.post("/upload-file", (req, res, next) => {
try {
upload(req, res, (err) => {
if (err) return res.json({ success: false, message: err.message });
if (!req.files.length)
return res.json({
success: false,
message: "Lütfen bir dosya seçiniz.",
});
if (err) return res.json({ success: false, message: err.message });
res.json({ success: true, message: "Dosya başarıyla yüklendi!" });
});
} catch (error) {
res.json({ success: false, message: error.message });
}
});
- Gelen dosyayı koşullandırma(sadece görsel vb.)
Bunun için üstteki kodlarda biraz değişiklik yapmamız gerekiyor.
Öncelikle koşul tanımlayalım;
const upload = multer({
storage,
fileFilter: (req, file, cb) => {
if (
file.mimetype == "image/png" ||
file.mimetype == "image/jpg" ||
file.mimetype == "image/jpeg"
)
cb(null, true);
else {
cb(null, false);
return cb(new Error("Lütfen sadece fotoğraf yükleyiniz!"));
}
},
}).array("files");
fileFilter
fonksiyonunu kullanarak gelen dosyanın tipine bakarak onu sunucuya yükleme/yüklememe işlemi yaptık.
Ve sonuç:
Ayrıca dosya boyutlarının istediğiniz aralıkta olması gibi diğer tüm koşullar için aşağıda bıraktığım kaynakça
kısmında multer
'in dokümantasyonuna bakabilirsiniz.
Not1: Hata çıkmaması için projemizin kök
dizininde uploads
adında bir klasör açmayı unutmayalım.
Not2: Ben projemi express-generator
ile oluşturduğum için tüm yapı hazır geldi. Eğer siz elle sıfırdan yazıyorsanız body-parser
kütüphanesini eklemeyi unutmayın.
Ve tüm işlemler bu kadar,
Okuduğunuz için teşekkürler görüşmek dileğiyle!🚀
Kaynakça & Kodlar
HTML KODLARI
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Deneme</title>
</head>
<body>
<input id="file" type="file" />
<button id="upload">Submit</button>
<script>
document.querySelector("#upload").addEventListener("click", async () => {
const fileInput = document.querySelector("#file");
const formData = new FormData();
for (let i = 0; i < fileInput.files.length; i++) {
const file = fileInput.files[i];
formData.append("files", file);
}
let response = await fetch("/upload-file", {
method: "POST",
body: formData,
});
response = await response.json();
console.log(response);
});
</script>
</body>
</html>
SERVER KODLARI
const express = require("express");
const router = express.Router();
const multer = require("multer");
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "uploads");
},
filename: (req, file, cb) => {
cb(null, file.originalname);
},
});
const upload = multer({
storage,
fileFilter: (req, file, cb) => {
if (
file.mimetype == "image/png" ||
file.mimetype == "image/jpg" ||
file.mimetype == "image/jpeg"
)
cb(null, true);
else {
cb(null, false);
return cb(new Error("Lütfen sadece fotoğraf yükleyiniz!"));
}
},
}).array("files");
router.post("/upload-file", (req, res, next) => {
try {
upload(req, res, (err) => {
if (err) return res.json({ success: false, message: err.message });
if (!req.files.length)
return res.json({
success: false,
message: "Lütfen bir dosya seçiniz.",
});
if (err) return res.json({ success: false, message: err.message });
res.json({ success: true, message: "Dosya başarıyla yüklendi!" });
});
} catch (error) {
res.json({ success: false, message: error.message });
}
});
module.exports = router;
