어떤 환경 문제로 인해 해당 프로젝트는 이런 구조로 되어있다.
browser ⇒ front server (요청을 proxy) ⇒ api 서버
즉 요청 시 이렇게 처리되고 있었다.
axios({
method: 'get',
url: '...생략.../download',
//...
**responseType: 'blob'**
})
router.get('~', async (req, res) => {
const res = await axios({
baseURL: 'API 서버 주소',
method: req.method,
url: req.url,
data: req.body
})
res.status(200).send(res.data);
// 에러 처리 생략!
// ...
})
문제는 2. proxyMiddleware 에서 api 서버로 API 요청할 때 responseType 을 지정하지 않아서 발생했다.
api 서버의 응답값으로는 binary 형태의 데이터가 리턴되는데, axios 로 요청 시 responseType을 binary 타입으로 지정해주지 않으면 깨진 형태로 받게된다.
타입 중 blob 과 arraybuffuer 가 binary 타입의 형태인데 이 중 blob 은 브라우저 전용 타입이다.
추가로 모든 요청에 대해 responeType 을 arraybuffer로 보낼 수는 없어 responseType 이 필요한 경우에만 요청하도록 분기처리가 필요했다. 두가지 방법이 있었다.
proxy 서버에 요청할 때 요청 헤더에 넘긴 후 proxyMiddleware 에서 headers 값을 확인하고, headers 에서 다시 특정 변수를 제거해주는 게 깔끔할 것 같아 1번 방법으로 처리했다.
또한 파일 다운로드 시 응답 헤더의 파일명을 사용해야하는 경우가 있어서 responseType 이 arraybuffer 로 지정된 경우 응답 헤더에 content-disposition 값을 그대로 append 해주도록 처리했다.
// proxyMiddleware.js
// 파일 다운로드 일 때 헤더에 파일명 전달
if (responseType === 'arraybuffer') {
const contentDispositionKey = 'content-disposition'
res.append(contentDispositionKey, response.headers[contentDispositionKey])
}