Ajax - data 옵션

Jung·2021년 11월 13일
0

TIL

목록 보기
51/77
post-custom-banner

캠프 타임어택 테스트를 보면서 궁금한 점이 생겼다.

이전에 플라스크를 사용해서 개발할 때 ajax 프론트 코드에서 아래와 같이 작성했다. (아래 코드는 예시)

<script>
    let name = "kj";
    let age = 25;
    $.ajax({
    	type: "POST",
        url: "/person",
    	data: {name: name, age: age},
        success: function (response) {
            // 로직 생략
        }
    });
</script>

'data 옵션에 서버로 요청할 데이터들을 넣어서 키-값 형태로 보내는구나' 라는 일차원적인 생각만 했다.

하지만 이번 타임어택 테스트를 볼 때는 JSON 포맷으로 데이터를 보낸다. 서버로 데이터를 전송하니까 이번에도 data 옵션에 기존에 하던대로 넣으면 되겠다 싶었다. 그래서 당연히 위에 적었던 코드처럼 작성했다.

Front

<script>
    let content = $('#content').val();
    $.ajax({
        type: 'POST',
        url: '/memo',
        data: {content: content},
        success: function (response) {
            // 로직
        }
    });
</script>

Back

@PostMapping("/memo")
public Memo addMemo(@RequestBody MemoDto memoDto) {
    Memo memo = memoService.createMemo(memoDto);
    return memo;
}

하지만 Exception이 발생하며 WARN 로그가 찍혔다.

org.springframework.web.HttpMediaTypeNotSupportedException:
Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

application/x-www-form-urlencoded를 사용할 때 Spring이 이를 RequestBody로 이해하지 못하는 것이라고 한다.

( 참고: https://stackoverflow.com/questions/33796218/content-type-application-x-www-form-urlencodedcharset-utf-8-not-supported-for )

근데 왜 Content-Type이 application/x-www-form-urlencoded로 되었지? 라는 생각을 가지며 ajax Content-Type의 디폴트 값을 찾아보았다. 역시 디폴트가 application/x-www-form-urlencoded였다.

(사진 출처: https://api.jquery.com/jquery.ajax/)

지금까지 플라스크를 사용하며 작성했던 ajax 코드들은 application/x-www-form-urlencoded 타입으로 이뤄졌던 것이다.

아무튼 !

data: {name: name, age: age}
data: {content: content}

이 부분은 application/x-www-form-urlencoded 타입이라는 것이다.

그러면 JSON 형식으로 보내려면 어떻게 해야할까?

<script>
    let content = $('#content').val();
    $.ajax({
        type: 'POST',
        url: '/memo',
        contentType: "application/json",
        data: JSON.stringify({content: content}),
        success: function (response) {
            // 로직
        }
    });
</script>

이와 같이 작성하면 된다.
contentType에 application/json으로 명시하고, data에도 JSON.stringify(json)를 사용한다.

JSON.stringify() 메서드는 JavaScript 값이나 객체를 JSON 문자열로 변환한다.

참고
“Post - Http: MDN.” HTTP | MDN, https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/POST.

“JSON.stringify() - Javascript: MDN.” JavaScript | MDN, https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify.


번외

application/x-www-form-urlencoded

POST / HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

name=kj&age=25

application/x-www-form-urlencoded도 요청 메시지 body 부분을 보면 키-값 형태로 되어있고 파라미터가 여러 개일 때 &로 구분한다. Spring에서 @RequestParam을 사용하면 파라미터 값을 가져올 수 있다.

application/json

POST / HTTP/1.1
Host: localhost
Content-Type: application/json

{
     "name": "kj",
      "age": 25
}

profile
97kim.github.io
post-custom-banner

0개의 댓글