node.js랑 express를 공부하고 리액트와 함께 미니 프로젝트 진행하고 돌아왔습니다.
그 중에서 제일 어떻게하는지 헤맸던 이미지 파일을 업로드하고 불러오는 과정입니다...
정말 도움을 많이 받은 참고한 블로그
npm install --save multer
먼저 multer 모듈을 다운받아 줍시다
const db = require("./models");
const { Image } = db;
const multer = require("multer");
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "upload/"); // cb 콜백함수를 통해 전송된 파일 저장 디렉토리 설정
},
filename: function (req, file, cb) {
cb(null, file.originalname); // cb 콜백함수를 통해 전송된 파일 이름 설정
},
});
var upload = multer({ storage });
app.use("/image", express.static("upload"));
//파일에 접근하기 디렉토리 경로 설정 /image 경로를 통해 upload폴더에 접근 할수있다
app.post("/api/images", upload.single("imageFile"), async (req, res) => {
// imageFile의 이름으로 들어온 파일을 req.file에 받아온다
console.log(req.file);
const newInfo = req.body;
if (req.file) {
const filePath = "http://localhost:3000/image/" + req.file.originalname;
//파일이미지를 불러오기위한 경로+이미지파일 이름
newInfo["imageFile"] = filePath;
//경로를 request의 json파일에 넣어 수정 해준다
}
const member = Member.build(newInfo);
await member.save();
});
app.get("/api/images/:id", async (req, res) => {
//아이디의 이미지를 찾음
const { id } = req.params; //:id자리에 올 값을 받아온다
const member = await Member.findOne({ where: { id } });
res.send(member);
});
app.js파일의 내용
파일을 업로드하기 위한 사전작업과 파일 이미지를 불러오기 위한 이미지의 src를 만드는 작업입니다.
참고로 console.log로 request를 통해 들어온 file을 찍어보면
{
[0] fieldname: 'imageUrl',
[0] originalname: 'IMG_3852.jpg',
[0] encoding: '7bit',
[0] mimetype: 'image/jpeg',
[0] destination: 'upload/',
[0] filename: 'IMG_3852.jpg',
[0] path: 'upload\IMG_3852.jpg',
[0] size: 55639
[0] }
이런식으로 찍혀서 file의 이름을 originalname으로 받아오는겁니다
import { useRef, useState } from "react";
export async function imageUpload(formData) {
await fetch(`http://localhost:3000/api/images`, {
method: "POST",
body: formData,
});
}
function Image() {
const inputRef = useRef();
const [imageFile, setImageFile] = useState(null);
console.log(imageFile);
const handleChange = (e) => {
const nextValue = e.target.files[0];
setImageFile(nextValue);
};
const uploadImage = async () => {
const formData = new FormData();
formData.append("imageFile", imageFile);
//이미지 파일을 formData로 json 형태로 만들어 전송하자
await imageUpload(formData);
//api
};
return (
<>
<form action="/" onSubmit={uploadImage} enctype="multipart/form-data">
<input
type="file"
accept="image/*"
onChange={handleChange}
ref={inputRef}
id="fileInput"
/>
<button type="submit">업로드</button>
</form>
</>
);
}
export default Image;
리액트 내에서 node.js를 통해 데이터를 보내기 위한 코드

이를 통해 업로드하면

이렇게 서버의 upload폴더에 저장이 됩니다

제 db엔 back.png가 2번 id로 들어가있네요
자 이제 이미지 파일을 업로드하고 해당 이미지의 경로를 저장했으니 불러오도록 합시다
import { useState } from "react";
export async function getImage(id) {
const res = await fetch(`http://localhost:3000/api/images/${id}`);
const body = await res.json();
return body;
}
function ImageShow() {
const [imageShow, setImageShow] = useState(null);
const loadImage = async () => {
const imageInfo = await getImage(2);
//처음 넣은 이미지의 아이디 1번
setImageShow(imageInfo.imageFile);
};
return (
<>
<img src={imageShow} alt="이미지를 불러와야 합니다" />
<button onClick={loadImage}>불러오기</button>
</>
);
}
export default ImageShow;
버튼을 클릭하면 이미지 경로를 불러와 이미지의 src로 만들어주면 서버의 이미지를 불러올 수 있다.
