반응형

최근에 jQuery로 만든 부분을 바닐라 JS로 바꾸고 있는데 이 과정에서 한 삽질 하나를 기록할 겸 글로 남긴다.

jQuery에서 사용하던 $.ajaxfetch로 바꿨다. 예를 들어 아래와 같은 코드가 있다면


$.ajax({
    url: 'https://httpbin.org/post',
    type: 'POST',
    cache: false,
    data: {
        aaa: 'a1',
        bbb: 'b1'
    },
    dataType: 'json'
}).done(function (data) {
    console.log(data);
});

이걸 인터넷 예제에 있는 대로 fetch로 바꿨더니


fetch('https://httpbin.org/post', {
    method: 'POST',
    cache: 'no-cache',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        aaa: 'a1',
        bbb: 'b1'
    })
}).then((response) => response.json()).then((data) => {
    console.log(data);
});

원래 코드들이 작동하지 않는다. 원인을 찾아보니 body에 있는 값을 가져오지 못한다. 알고 봤더니 Content-Type을 json으로 지정해서 form data로 인식하지 못해서였다.

form data를 보내려면 Content-Type을 application/x-www-form-urlencoded로 지정해야 한다. (옛날에도 졸업작품 만들다가 비슷한 삽질을 했던 거 같은데...)

타입만 바꾸면 끝이 아니다. body도 json이 아닌 form data 형식에 맞춰서 보내야 한다.


fetch('https://httpbin.org/post', {
    method: 'POST',
    cache: 'no-cache',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: 'aaa=a1&bbb=b1'
}).then((response) => response.json()).then((data) => {
    console.log(data);
});

이제 원래 코드들도 잘 작동한다.

그런데 $.ajax를 사용할 때처럼 깔끔하게 object를 보내지 못하고 form data 형식 문자열을 넣어줘야 하는 부분이 불편해서 더 찾아봤더니 방법이 있었다. URLSearchParams를 사용하면 된다.


fetch('https://httpbin.org/post', {
    method: 'POST',
    cache: 'no-cache',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
        aaa: 'a1',
        bbb: 'b1'
    })
}).then((response) => response.json()).then((data) => {
    console.log(data);
});

조금 더 테스트해보니 굳이 Content-Type을 지정하지 않아도 알아서 application/x-www-form-urlencoded로 지정됐다. 그리고 이왕 명시적으로 지정할 거면 인코딩 정보까지 넣어서 application/x-www-form-urlencoded; charset=UTF-8이라고 지정하는 게 더 좋을 것 같다.

사실 별거 아닌 건데 인터넷에는 죄다 json으로 보내는 예제(아니면 파일 업로드)밖에 없어서 처음 사용할 때 혼란이 있었다. 왜 기본적인 form data 예제가 없었을까... form data는 주로 html에서 form 태그로 보내니까 ajax에서는 필요가 없어서 그런가?

반응형

+ Recent posts