728x90
https://medium.com/@hassaanistic/image-handeling-using-multer-in-react-d7fea28e8dc6
multer 를 이용하여 이미지를 업로드하는 방법은 두가지가 있다. 첫번째는 이미지를 서버로 전송하면 특정폴더에 저장하고, 폴더에 저장된 이미지 데이터를 DB에 저장하고, 브라우저로 이미지 데이터를 보낸다. 두번째는 이미지를 서버로 전송하면 특정폴더에 저장하고, 폴더에 저장된 이미지 경로를 브라우저로 전송하고, 브라우저에서 해당경로의 파일 데이터를 읽는 방식이다. 즉, 브라우저로 이미지 데이터를 보내느냐, 이미지 경로를 보내느냐의 차이다. 또는 서버쪽에서 이미지 데이터를 조회하느냐 프론트쪽에서 이미지 데이터를 조회하느냐의 차이다.
아래 코드는 두번째 방법을 사용한다. 두번째 방법의 단점은 이미지 리스트를 보여줘야 할때 예를 들어 이미지가 1000개이면 서버접속을 1000번 해야된다. 물론 상세페이지에서 하나의 이미지를 보여주는건 가능하다. 하지만 첫번째 방법으로 하면 이미지 데이터의 리스트를 한번의 서버접속으로 조회할 수 있다.
Creating image model
const mongoose = require('mongoose');
const imageSchema = new mongoose.Schema({
name: String,
contentType: String,
imageUrl: String, // Store the image URL here ->// we can fetch the image from databse using this
// Add any other fields you need for your image
});
module.exports = mongoose.model('Image', imageSchema);
Creating Middleware
const multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, ("./uploads") ); // ->("./uploads") this is the destination where files will save in the HArdDisk Storage
},
filename: (req, file, callback) => {
callback(null, file.originalname);
},
});
// const upload = multer({ storage :storage }); OR
const upload = multer({ storage });
module.exports = upload;
// memoryStorage() vs diskStorage() ? : {
// const storage = multer.memoryStorage(); // It open the image in the Ram temporarily --> Not save permanently -> good for croping , editing , and making change in the file Function without saving the copy permanently
//we use memoryStorage if we don't need to save the image permanently and for future use
//In our case we have to use the disk storage to save the images permanently for the future use
//}
Server Room
const express = require('express');
const db = require("./config/connectToDatabase")
const app = express();
const PORT = process.env.PORT ;
const imageRouter = require("./routes/imageRoutes");
var cors = require('cors') //For connecting Backend with frontend
app.use(express.json());
app.use(cors());
app.get('/', (req,res )=>{
res.send("Hello MEDIUM");
});
app.use('/api/images',imageRouter);
app.listen(PORT , (req, res) => {
console.log(`Running at http://localhost:${PORT}`);
});
Routes file
const express = require('express');
const router = express.Router();
const upload = require('../middlewares/multerStorage'); // Import the multer middleware
const {postingImage ,singleImage } = require('../controller/imageController'); // Import the image controller
router.post('/upload', upload.single('image'), postingImage); // Call the imageController.uploadImage function
router.route('/:id').get(singleImage)
module.exports = router;
Control Room for Image APIs
const Image = require("../models/imageModel");
const path = require("path"); //for single specific Image
const fs = require('fs'); //for single specific Image
// @Posting Image using POST
// http://localhost:5000/api/images/upload
const postingImage = async (req, res) => {
try {
// Create an Image model instance.
const image = new Image({
name: req.file.originalname,
contentType: req.file.mimetype,
imageId: req.file.id,
});
// Save the Image model instance to the database.
const savedImage = await image.save();
// Set the imageUrl based on your server URL and the image ID
savedImage.imageUrl = `http://localhost:5000/api/images/${savedImage._id}`;
//this is for getting the image from the database
// Save the updated Image model
await savedImage.save();
res.json(savedImage);
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Image upload failed' });
}
}
// @Getting Specific Image using GET
// http://localhost:5000/api/images/:id
const singleImage = async (req, res) => {
try {
const image = await Image.findById(req.params.id); //req -> local:Url
// await console.log(image.name)
if (!image) {
return res.status(404).json({ error: 'Image not found' });
}
// Construct the path to the image file in the uploads folder based on _id
// const imagePath = path.join(__dirname, 'uploads', `${req.user._id}-${image.name}`); //"will use when add authentication"
// const imagePath = path.join(__dirname, 'uploads', `${image.name}`); //this is disgusting `${}`
const imagePath = path.join(__dirname, '..', 'uploads', image.name);
// console.log(imagePath);
// Check if the file exists
if (!fs.existsSync(imagePath)) {
return res.status(404).json({ error: 'Image file not found' });
}
// Send the image file as a response
res.sendFile(imagePath);
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Failed to retrieve image' });
}
}
module.exports = { postingImage, singleImage,};
FrontEnd part
import React, { useEffect, useState } from "react";
import {Buttons} from "@chakra-ui/react";
export default function Profile() {
const [fileInput, setFileInput] = useState(null);
const [selectedImageForDisplay, setselectedImageForDisplay] = useState(null);
useEffect(() => {
// Check if there's a saved image URL in localStorage and set it
const savedImageURL = localStorage.getItem("selectedImageForDisplay");
if (savedImageURL) {
setselectedImageForDisplay(savedImageURL);
}
}, []);
const onChangeHandle = (e) => {
setFileInput(e.target.files[0]);
};
const handleImageUpload = () => {
if (fileInput) {
const formData = new FormData();
formData.append("image", fileInput);
fetch("http://localhost:5000/api/images/upload", {
method: "POST",
body: formData,
headers: {
'Authorization': `Bearer ${localStorage.getItem("token")}`,
}
})
.then((response) => {
if (response.ok) {
return response.json();
}
throw new Error("Image upload failed.");
})
.then((data) => {
fetchAndDisplayImage(data.imageUrl);
})
.catch((error) => {
console.error("Error uploading image:", error);
});
}
};
const fetchAndDisplayImage = (imageUrl) => {
fetch(imageUrl, {
method: "GET",
headers: {
'Authorization': `Bearer ${localStorage.getItem("token")}`,
}
})
.then((response) => {
if (response.ok) {
return response.blob();
}
throw new Error("Failed to fetch the image.");
})
.then((blob) => {
const url = URL.createObjectURL(blob);
setselectedImageForDisplay(url);
// Save the image URL in localStorage
localStorage.setItem("selectedImageForDisplay", url);
})
.catch((error) => {
console.error("Error fetching image:", error);
});
};
return (
<div>
<input
type="file"
accept="image/*"
onChange={onChangeHandle}
/>
<Button
bg={"purple.300"}
onClick={handleImageUpload}
style={{ margin: "20px" }}
>
Upload Image
</Button>
{selectedImageForDisplay && (
<div style={{ width: "200px", height: "200px" }}>
<img
src={selectedImageForDisplay}
alt="Selected"
style={{ width: "100%", height: "100%" }}
/>
</div>
)}
</div>
);
}
728x90
'백엔드 > express.js' 카테고리의 다른 글
조건쿼리 (conditional query) (0) | 2024.05.20 |
---|---|
ESModule 로 express 작성하기 (0) | 2024.05.17 |
노드 cors 에러 해결하기 - Error: unable to verify the first certificate (0) | 2024.05.16 |
express 문서 - 미들웨어 코드 (0) | 2024.04.15 |
express 프레임워크 기본이론 (0) | 2021.10.12 |