티스토리 뷰

반응형

백엔드 배운지 일주일 정도 되었는데 쉽지않다!

그래도 계속해서 반복하면 언젠간 쉬워지겠지 제발

오늘 배운 파일업로드와 실습문제에서 가장 헤맸던 부분을 기록해 보았다.

 

 

 

실습 - 이미지를 업로드 하고 render된 페이지에서 이미지 보여주기

 

 

1. 폼페이지 만들기

<!DOCTYPE html>
<html lang="en">
  <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" />
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

    <title>실습</title>
  </head>
  <body>
    <h1>개인정보</h1>
    //multer 사용시 enctype="multipart/form-data" 꼭!!
    <form action="/join" method="POST" enctype="multipart/form-data"> 
      <label for="userid">아이디 :</label>
      <input type="text" id="userid" name="userid" />
      <br />
      <label for="userpw">비밀번호 :</label>
      <input type="password" id="userpw" name="userpw" />
      <br />
      <label for="username">이름 :</label>
      <input type="text" id="username" name="username" />
      <br />
      <label for="userage">나이 :</label>
      <input type="number" id="userage" name="userage" />
      <br />
      <label for="userfile">프로필사진 :</label>
      <input type="file" name="fileName" id="fileName" />
      <br />
      <button type="submit">회원가입</button>
    </form>
  </body>
</html>

*multer이용시 form태그에 속성으로 enctype="multipart/form-data" 꼭!! 

 

 

 

 

2. 결과 페이지 만들기

<!DOCTYPE html>
<html lang="en">
  <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>실습결과</title>
  </head>
  <body>
    <h3>아이디 : <%= userInfo.id%></h3>
    <h3>비밀번호 : <%= userInfo.pw%></h3>
    <h3>이름 : <%= userInfo.name%></h3>
    <h3>나이 : <%= userInfo.age%></h3>
    <img src="/uploads/<%= userInfo.file%>" width="100px" />
  </body>
</html>

 

 

 

 

3. 대망의 서버

const express = require("express");
const app = express();
const PORT = 8000;
const path = require("path");

//multer 설정
const multer = require("multer");
const upload = multer({
  // 파일 저장 경로 ( 설정이 없으면 기본 저장만 되므로 설정까지 같이 하는 작업 필요)
  dest: "uploads/",
});

//요게 업로드 설정하는 작업
const uploadDetail = multer({
  storage: multer.diskStorage({
    destination(req, file, done) {
      done(null, "uploads/");
    },
    //파일이름 넣어주기
    filename(req, file, done) {
      const ext = path.extname(file.originalname); //파일의 확장자만 가져옴 ex)jpg,pdf등
      done(null, path.basename(file.originalname, ext) + Date.now() + ext); //파일의 원래 이름만 가져오기 위해 위에서 구한 확장자명을 지우고 날짜를 넣고 다시 확장자를 붙임
    },
  }),
  limits: { fileSize: 5 * 1024 * 1024 }, //파일 사이즈
});

//템플릿
app.set("view engine", "ejs");
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

//폴더에서 파일가져올수있음
app.use("/views", express.static(__dirname + "/views"));
app.use("/uploads", express.static(__dirname + "/uploads"));
//맨앞에 경로가 붙으면 로컬호스트/경로/파일이름?

//과제
app.get("/practice", function (req, res) {
  res.render("practice");
});
// /join으로 들어갔을때 result.ejs 렌더링
app.post("/join", uploadDetail.single("fileName"), function (req, res) {
  // res.send(req.body);
  console.log(req.file);
  res.render("result", {
    userInfo: {
      id: req.body.userid,
      pw: req.body.userpw,
      name: req.body.username,
      age: req.body.userage,
      file: req.file.filename,
    },
  });
});

app.listen(PORT, () => {
  console.log(`로컬호스트 ${PORT}`);
});

 

 

※ 파일이름 만드는 방법

● path.extname → 파일경로의 확장자를 반환

ex) path.extname(test.jpg) → jpg만 남음

 

● path.basename → 파일경로에서 파일의 기본 이름만 반환

ex)path.basename(test.jpg, .jpg) → test만 남음

//파일이름 넣어주기
    filename(req, file, done) {
      const ext = path.extname(file.originalname); //파일의 확장자만 가져옴 ex)jpg,pdf등
      done(null, path.basename(file.originalname, ext) + Date.now() + ext);
      //파일의 기본 이름만 가져오기 위해 ext 변수를 사용해서확장자명을 지우고
      //파일이름에 현재 시간 나타내는 Date.now()를 붙이고 다시 확장자를 붙임
      //Date.now()는 현재시간을 구해주는 함수로 파일이름의 고유성을 위해 붙이는 것,
    },

 

 

 

그리고 서버에서 제에에일 헤맨 부분

file에 어떤 값을 넣어야 할지 계속 헤매다가

console.log(req.file) 해보고 알았다

filename......

 

app.post("/join", uploadDetail.single("fileName"), function (req, res) {
  // res.send(req.body);
  console.log(req.file);
  res.render("result", {
    userInfo: {
      id: req.body.userid,
      pw: req.body.userpw,
      name: req.body.username,
      age: req.body.userage,
      file: req.file.filename,
    },
  });
});

 

 

파일 한개만 업로드

 

- ejs 코드

    <h4>싱글 파일업로드</h4>
    <!--multer는 멀티파트폼데이터만 사용할 수 있음-->
    <form action="/upload" method="POST" enctype="multipart/form-data">
      <input type="text" name="title" />
      <!--여기 name값이 백엔드의 /upload로 들어감-->
      <input type="file" name="fileName" />
      <br />
      <button type="submit">업로드</button>
    </form>

 

- 서버 코드

app.post('form 경로', uploadDetail.single("클라이언트에서 input 태그 name 값"),function(req,res){ 실행할 코드 })

//single : 싱글파일 업로드
app.post("/upload", uploadDetail.single("fileName"), function (req, res) {
  //위의 upload때문에 upload.single 해준것
  res.send("싱글 파일업로드");
});

*uploadDetail.single을 사용하여 파일에 접근 후

multer을 사용하여 파일을 업로드 하고

' req.file ' 객체에 저장!

라우터에서 req.file을 통해 해당 파일에 접근할 수 있음

 

 

 

파일 여러개 업로드 버전 2개

 

● 여러개 파일 업로드

 

- ejs 코드

*파일 여러개 업로드시 input에 multiple 속성을 추가해야함

    <form action="/upload/array" method="POST" enctype="multipart/form-data">
      <!--multiple 붙여야 파일 여러개 고를수있음-->
      <input type="file" name="fileName" multiple />
      <button type="submit">업로드</button>
    </form>

 

- 서버 코드

app.post('form 경로', uploadDetail.array("클라이언트에서 input 태그 name 값"),function(req,res){ 실행할 코드 })

//array : 파일 여러개 업로드
app.post("/upload/array", uploadDetail.array("fileName"), function (req, res) {
  res.send("멀티파일 업로드");
});

*uploadDetail.single을 사용하여 파일에 접근 후

multer을 사용하여 파일을 업로드 하고

' req.files ' 객체에 저장!

라우터에서 req.files을 통해 해당 파일에 접근할 수 있음

 

 

 

● 여러개 파일 개별 업로드

 

- ejs 코드

*파일 여러개 업로드시 input에 multiple 속성을 추가해야함

<h4>여러개 각각 파일 업로드</h4>
    <form action="/upload/fields" method="POST" enctype="multipart/form-data">
      <input type="file" name="fileName1" multiple /> 
      <br />
      <input type="file" name="fileName2" multiple />
      <input type="submit" value="업로드" />
    </form>

 

- 서버 코드

//fields : 파일 여러개 따로 업로드
app.post(
  "/upload/fields",
  uploadDetail.fields([{ name: "fileName1" }, { name: "fileName2" }]),
  function (req, res) {
    res.send("각각 멀티파일 업로드");
  }
);

 

 

 

axios로 동적파일 업로드

 

- ejs 코드

<h4>동적 파일 업로드</h4>
    <input type="file" name="dynamicUpload" id="dynamicUpload" />
    <button type="button" onclick="upload()">업로드</button>
    <br />
    <img id="img" width="100px" /> <!--이미지 들어올 자리-->
    
    <script>
      function upload() {
        const formData = new FormData(); //form을 동적으로 제어
        const file = document.querySelector("#dynamicUpload"); //file 타입 인풋 태그 가져오기
        formData.append("dynamicUpload", file.files[0]); //dynamicUpload은 서버에서 해당파일을 식별하기 위한 키값
        console.log(file.files[0]); //file.files[0] : input에 넣은 사진 가져와라

        axios({
          method: "POST",
          url: "/dynamic",
          data: formData,
          headers: {
            "Content-Type": "multipart/form-data",
          },
        }).then(function (response) {
          console.log(response);
          const img = document.querySelector("#img");
          img.setAttribute("src", response.data.path); //img태그에 src 속성 추가해서 이미지 보이게
        });
      }
    </script>

axios는 클라이언트 측에서 HTTP 요청을 보내는 데 사용되는 js 라이브러리로 주로 서버와의 데이터 통신을 단순화하고 비동기적인 요청을 처리하는 데에 활용됨

 

 

*axios의 옵션

  • method: HTTP 요청 메서드
  • url : 요청을 보낼 서버의 URL
  • data : 요청에 함께 전송할 데이터
  • headers: 요청의 헤더를 설정, "Content-Type": "multipart/form-data"를 설정하여 멀티파트 폼 데이터를 전송

 

 

axios의 then() 메서드를 사용하여 요청이 성공적으로 완료되었을 때 처리할 콜백 함수를 등록할 수 있음

위의 코드에서는 데이터를 받아와서 response 객체에 저장하고, 이를 활용하여 이미지 태그의 src 속성을 설정하여 이미지를 표시하고 있음

 

 

 

 

 

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함