Multipart: Boundary not found 에러지만 고친건 react 코드

Joo·2024년 3월 10일

Learning POP

목록 보기
2/3
post-thumbnail

++ 사이드 플젝 하면서 겪은 삽질 시리즈

문제상황

react에서 fetch로 post요청을 보냈을 때, 이미지와 json데이터를 한번에 보내야 했기 때문에 아래 코드처럼 headers에 Content-Type 을 설정했다.

const fetchOption = (method: string, reqData?: any) => {
    if (method === "GET" || method === "DELETE") return { method }
    else if (method ===  "POST" || method === "PUT" || method === "PATCH") {
        return {
            method,
           	headers: {
            "Content-Type": "multipart/form-data",
            "Accept":"application/json"
            },
            body: reqData
        }
    }
}

서버에서 req.body 를 출력해봤지만 값이 전혀 안왔다. 또 뇌정지,,

express - react 간 이미지 파일 전송에 추가적인 옵션이 필요한가 싶어서 이것저것 찾아보다 결국 원점으로 돌아옴..

에러 헨들링 잊지 말기..

콘솔에 에러가 왜 안나오나 했는데 express에서 에러 헨들링 미들웨어를 사용해놓고 따로 출력은 안하고 있었다..ㅋㅋ

아래 코드처럼 에러 헨들링 미들웨어는 4개의 인자가 필요하다. 앞선 api 코드에서 에러가 발생하면 에러 헨들링 미들웨어가 실행된다. 그래서 api 함수 아래에 위치해야 함.

app.use((err, req, res, next) => {
    console.log(err);
    res.send(err);
})

https://expressjs.com/ko/guide/error-handling.html

다시 본론으로 돌아오면, Multipart: Boundary not found 이런 에러가 발생했다.
post api가 실행되기 전에 multipart/form-data 를 사용하기 위해 multer 미들웨어를 먼저 실행한다.

const multer = require("multer");
const { storage } = require("../cloudinary/index");
const upload = multer({ storage }); // 이미지 저장소 설정

router.route("/")
    .post(upload.single("image"), wrapAsync(popsongs.createPopsong))

저 부분에서 에러가 발생했으니 애초에 post api 호출도 못했고, req.body도 값을 출력할 수 없었던 것이다.

fetch가 알아서 한다고?

클라이언트 측 fetch 옵션을 보면 Content-Type을 직접 정의해 줬는데, 큰 파일을 조각조각 나눌 바운더리를 정의해줘야 한다.

Content-Type: multipart/form-data; boundary=something

하지만 fetch에 Content-Type 을 정의하지 않아도 알아서 바운더리까지 정의해준다.

const fetchOption = (method: string, reqData?: any) => {
    if (method === "GET" || method === "DELETE") return { method }
    else if (method ===  "POST" || method === "PUT" || method === "PATCH") {
        return {
            method,
           	headers: {
            ("Content-Type": "multipart/form-data",)
            "Accept":"application/json"
            },
            body: reqData
        }
    }
}

정확히는 웹 브라우저에서 서버에 요청을 보낼 때, 데이터 타입을 판단하기 때문에 가능한 거였다.

MIME 스니핑

MIME 유형이 없거나 브라우저가 MIME 유형이 올바르지 않다고 판단하는 경우 브라우저는 리소스의 바이트를 보고 올바른 MIME 유형을 추측하는 MIME 스니핑을 수행할 수 있습니다.

각 브라우저는 서로 다른 상황에서 MIME 스니핑을 다르게 수행합니다. (예를 들어, Safari는 전송된 MIME 유형이 적합하지 않은 경우 URL의 파일 확장자를 확인합니다.) 일부 MIME 유형은 실행 가능한 콘텐츠를 나타내므로 보안 문제가 있습니다. 서버는 헤더를 전송하여 MIME 스니핑을 방지할 수 있습니다.

경고: 브라우저는 파일 확장자가 아닌 MIME 유형을 사용하여 URL 처리 방법을 결정하므로 웹 서버가 응답 Content-Type헤더에 올바른 MIME 유형을 보내는 것이 중요합니다. 이것이 올바르게 구성되지 않으면 브라우저가 파일 내용을 잘못 해석할 가능성이 높으며, 사이트가 제대로 작동하지 않으며, 다운로드한 파일이 잘못 처리될 수 있습니다.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

위 MDN 문서에 따르면, 브라우저가 데이터 유형을 판단하고 설정할 수 있지만 정확한 리소스를 주고 받기 위해서는 Content-Type을 설정해두지 않으면 예상치 못한 결과가 일어날 수 있다.

삽질을 하면서,,

원인을 알면 대부분의 문제들을 해결할 수 있다. 개발자가 에러를 쉽게 파악하고 관리할 수 있는 에러 헨들링의 중요성을 다시금 느낀다.

profile
한 줄이 모여 책이 되듯 기록하기

0개의 댓글