express 정적 파일 서비스 & 정적 파일 다운로드 api 개발

쩡아지🐶·2024년 2월 22일

express 질문저장소

목록 보기
3/5
post-thumbnail

/images/{파일명} 으로 접근 시 images 폴더 하위의 파일을 서비스한다고 할 때

/**
 * 정적 파일 서비스
 */
app.use('/images', express.static('images'));

다운로드하는 API는 아래의 조건을 추가하였다.

  1. post method 사용
  2. request에서 payload 데이터를 받아서 관련 파일을 다운로드
  3. 관련 파일을 못찾는 등의 로직 에러와 로직 성공을 구분하기 위해 response 헤더에 커스텀 헤더를 추가

// 1) 기본 기능을 벗어나는 순간 OPTIONS으로 handshaking을 하기 때문에 cors method에 OPTIONS 추가 해줘야한다
// 2) request에서 받은 데이터(queryString, pathVariable, payload)를 파싱하기 위해 옵션 추가
app.use(
  cors({
    methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS']
  }),
  // querystring 파싱 (req.query)
  express.urlencoded({
    extended: true
  }),
  // request payload 파싱 (req.body)
  express.json()
);

// 정적 파일 다운로드
// 1) payload body 타입 선언 (Request의 3번째 타입이 body 타입이다)
// 2) 서버가 주는 커스텀 헤더를 front에서 사용하려면 노출시켜야한다! Access-Control-Expose-Headers 꼭 설정하기
app.post(
  '/download',
  (
    req: Request<
      {},
      {},
      {
        contType?: ContType;
        contId?: number;
      }
    >,
    res: Response
  ) => {
    try {
      if (req.body.contType === 'P') {
        const target = photosParsed.find(
          (item) => item.contId === req.body.contId
        );

        if (target && target.filePath) {
          res
            .status(200)
            .header({
              'Download-Success': 'Y',
              'Access-Control-Expose-Headers': [
                'Download-Success',
                'Content-Disposition'
              ]
            })
            .attachment(target.fileName || target.filePath)
            .download(path.join(__dirname, '..', target.filePath));
        } else {
          res.status(200).send(make500Response('다운로드할 이미지가 없습니다.'));
        }
      } else {
        res.status(200).send(make500Response('컨텐츠 타입을 확인하세요.'));
      }
    } catch (e) {
      res
        .status(200)
        .send(make500Response(e instanceof Error ? e.message : String(e)));
    }
  }
);

서버가 추가한 헤더를 axios에서 다 가져다 쓸 수 있는줄 알았는데 아니었음.
CORS 허용 목록에 포함한 헤더가 아니면 기본적으로 프론트에서는 사용할 수 없고, 서버에서 예외적으로 노출한다고 헤더에 명시해줘야한다.

profile
React, Next.js, Express STUDY

0개의 댓글