본문 바로가기

Youtube Clone Coding

파일 업로드

영상 파일을 업로드 하기 이전에 일단 유저의 프로필 사진을 업로드 하는 것을 구현한다. 이전에 user 객체 안에 avatarUrl 이라는 변수가 있었다. 이는 깃허브에서 제공한 것이고 유저의 프로필 사진의 url을 저장해둔 것이다.

일단 파일을 업로드하기 위해 유저의 프로필 수정 페이지에 파일 업로드 input을 만들어주었다.

input(type="file", id="avatar",name="avatar",accept="image/*")

이는 이미지 형식의 파일을(.jpg .jpeg .png 등..) 모두 받을 수 있는 input이된다. 이제 파일을 받기 위해 multer 라는 미들웨어를 사용하는데 이는 npm 을 통해서 다운로드 받고 사용한다. multer은 우리가 form으로 보낸 파일을 받아서 업로드 해주는 역할을 한다. 

export const uploadFiles = multer({ dest: "uploads/" });

이렇게 미들웨어 파일에 작성을 해주면 파일의 destination 이 uploads 가 되고, uploads 파일은 자동으로 생성된다. 그리고 multer는 다음에 호출되는 컨트롤러에 파일에 관한 정보를 제공한다.

userRouter.route("/edit").all(protectorMiddleware).get(getEdit).post(uploadFiles.single("avatar"), postEdit);

이렇게 post 요청시 multer를 미들웨어로 사용하면 postEdit 컨트롤러에서는 req.file을 통해 파일의 정보에 접근 할 수 있게된다. 

이제 postEdit 컨트롤러에서 유저의 avatarUrl을 업데이트 해주면 되는것인데, 유저가 프로필 사진을 바꾸지 않는경우에는 req.file이 undefined가 되어버린다. 따라서 3항연산자를 통해 avatarUrl을 업데이트하거나 그대로 유지한다. 

const updatedUser = await User.findByIdAndUpdate(id, {
        avatarUrl: file ? file.path : avatarUrl,
        name: name,
        email: email,
        username: username,
        location: location,
}, { new: true });
req.session.user = updatedUser;

file이 있다면 (true) file.path가 저장될 것이고 없다면 (false) 원래의 값이 그대로 유지된다.

 

이제 해당 사진을 프로필에 보여주기 위해 다음과 같은 코드를 프로필 수정 템플릿에 작성한다.

img(src="/" + loggedInUser.avatarUrl, width="100",height="100")

하지만 브라우저는 /uploads/파일의경로~ 같은 url을 이해할 수 없다. 왜냐면 내가 만든적이 없는 url 이니깐ㅇㅇ. 그래서 나는 익스프레스의 static 메서드를 이용해서 "누군가가 /uploads~ 로 가려한다면 uploads 폴더의 내용을 보여 주셈" 과 같은 코드를 작성했다.

app.use("/uploads", express.static("uploads"));

이렇게 되면 브라우저는 해당 url을 이해하고 사진을 보여준다. 

 

*** 절대 절대 절대 DB에 파일을 저장하면 안된다. DB에는 파일의 위치만 저장한다. 

'Youtube Clone Coding' 카테고리의 다른 글

유저 프로필 페이지  (2) 2022.11.22
영상 파일 업로드  (0) 2022.11.21
비밀번호 변경  (0) 2022.11.21
사용자 프로필 수정  (0) 2022.11.17
카카오로 로그인 하기  (0) 2022.11.17