Static Files and Recap

0_CyberLover_0·2022년 4월 28일
0

Node.JS #05

목록 보기
17/19

현재 브라우저가 uploads폴더에 있는 내용을 볼수 있게 해야한다.

브라우저가 서버에 있는 파일에 접근할수 없으니까 그렇다. 브라우저한테 어디로 가야 하는지 얘기해줘야 한다.

그리고 브라우저가 서버의 어떤 폴더로든 갈수 있는건 보안상 좋지 않다.

그래서 브라우저가 어떤 페이지와 폴더를 볼수 있는지 알려줘야 한다.

그러기 위해 static files serving이라는걸 활성화 해준다.

폴더 전체를 브라우저에게 노출시킨다는 의미이다. 폴더를 만들고 그 폴더를 브라우저에게 노출 시키는 거다.

먼저 /uploads route를 만들어야 한다.

server.js에서

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

app.use를 써서 "/uploads"로 간다면 그리고 폴더를 노출시킨다.

노출시키는 방법은 express.static()이다.

static()에는 노출시키고 싶은 폴더의 이름을 쓰면 된다.

vsc에서 정의를 보면 디렉토리 내부의 파일을 제공한다고 명시되어 있다.

그래서 "uploads"를 입력해 주면 된다. 새로고침을 하면 이미지가 안나오던데

서버는 잘 받고 있는데 서버에서 에러가 나던데 서버를 껐다 다시 재시작 해주니 잘 작동한다.

새탭에서 이미지를 열면 확장가 없어서 다운로드 할려고 한다.

확장자는 없지만 컴퓨터는 이해하고 있다. 브라우저도 이해하고 있다는 말이다.

다시 한번 말하자면 처음 원했던건 파일을 업로드 하는거였다.

서버로 파일을 보내고 싶었다. 먼저 viewsedit-profile에 파일을 받는 input을 만들었다.

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

그리고 다른 파일은 필요 없으니 이미지만 받는다고 설정했다.

파일 input을 만들었고 원하는건 서버에 이미지를 저장하고 그 이미지에 대한 정보를 얻는거였다.

그래서 multer라는 middelware를 사용했다.

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

form으로 보낸 파일을 업로드 해주고, 그 파일에 관한 정보도 제공해주고 다른 기능도 있다.

예를 들면 파일명을 완전히 랜덤으로 생성해준다는 거다.

만약 두명의 유저가 selfile라는 같은 이름의 파일을 업로드 해도 multer가 이름을 바꿔 주기 때문에 아무 문제 없다.

그리고 그 파일을 지정한 폴더에 저장해준다.

그리고 다음 순서의 controller에 파일에 관한 정보를 제공한다.

routers에서 multer를 먼저 사용해주고

userRouter.js에서

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

그 다음 postEdit controller를 사용하면 multer가 시작된다.

파일이 업로드 되고 파일명이 바뀌고 파일이 uploads폴더에 저장되고

그 파일에 관한 정보를 받아서 postEdit에 전달해 주는 거다.

userController.js에서

export const postEdit = async (req, res) => {
  const {
    session: {
      user: { _id, avatarUrl },
    },
    body: { name, email, username, location },
    file,
  } = req;
  const exists = await User.exists({
    _id: { $ne: { _id } },
    $or: [{ username }, { email }],
  });

그리고 postEdit에서 req.file을 사용할수 있다.

postEdit에서는 avatarUrl을 업데이트 할수 있는데 때로는 유저가 파일을 보내지 않을수도 있다.

그래서 꼭 확인해야 한다. formfile이 있다면 req에 있는 file object를 사용 할수 있다는거고 그말은 file.path가 존재한다는 거다.

그런데 formfile이 없다면 useravatarUrl은 기존의 것이랑 같다.

기존의 avatarUrl은 어디서 오는거냐면 req.session.user.avatarUrl에서 오는 거다.

기존 avatarUrl을 현재 로그인된 유저로 부터 가져오는 거다.

그리고 avatarUrl이 생기긴 했지만 그걸로는 충분하지 않다.

브라우저가 아직 이 파일이 존재하는지 모르기 때문이다.시도해봤지만 404에러가 뜨고 작동하지 않았다.

작동하지 않은 이유는 서버가 /uploads/랜덤값라는url을 이해하도록 설정되지 않아서 그랬다.

그래서 server.js에서

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

Express에게 만약 누군가 /uploads로 가려고 한다면 uploads폴더의 내용을 보여주라고 했다.

uploads폴더는 multer가 파일을 저장하는 곳이다.

만약 다른 사진을 새로 아바타로 설정한다면 폴더에 또 새로운 이미지 파일이 생기는거다.

사이트가 활성화 되었을때 트래픽량이나 여러 모로 안 좋을것 같다.

이 방법의 문제점을 해결해 보도록 한다.

첫번째 문제점은 파일을 서버에 저장한다는거다. 좋은 생각이 아니다. 서버는 계속 종료되고 다시 시작하는걸 반복한다.

뭔가를 업데이트하면 새로운 서버를 만들어서 다시 시작하는거다.

그 전 서버에 저장 돼있던 파일들은 날아가는거다.

그렇다면 서버가 두개 필요하다면 어떨까? 하나의 백엔드를 만들더라도 서버 두개가 필요할때가 있다.

방문자가 너무 많으면 그럴수도 있다. 그럼 두개의 서버에서 uploads폴더를 공유해야 하나? 그건 너무 이상하다.

서버가 죽으면 어떻게 될까?

서버가 죽으면 서버를 시작할수 있는 코드를 가지고 다른 서버에서 다시 시작하면 된다.

그런데 서버가 죽었을때 코드와 업로드된 파일들이 있다면 파일은 날리는 거다.

그래서 나중에 이방법을 바꿀 건데 파일을 서버에 저장하는게 아니라 다른곳에 저장하는거다.

서버가 사라졌다 다시 돌아와도 파일은 그대로 있도록 말이다. 파일을 안전하게 저장하는거다.

이건 나중에 실제 서버에 배포할때 해본다.

한가지 꼭 기억할게 있다. DB에 절대 파일을 저장하면 안된다.

DB에는 파일 자체가 아니라 파일의 위치를 저장하는거다.

그래서 파일 원본은 Amazon의 하드드라이브 같은데 저장하면된다.

DB에는 url을 저장하면 된다.

다음 파트에서는 배운걸 연습하고 video model에 한가지를 추가할거다.

video model에는 video file이 없다.

아바타에 했던걸 활용해서 video file url을 만들어 본다.

profile
꿈꾸는 개발자

0개의 댓글