ajax로여러 Content-Type 보낼 수 있나?

Jung·2021년 11월 26일
2

TIL

목록 보기
60/77
post-thumbnail
post-custom-banner
<form enctype="multipart/form-data">
    input 태그 ...
</form>
<script>
function example() {
    let data = {
        inputTextA: $('#inputTextA').val(),
        inputTextB: $('#inputTextB').val(),
    }
    let fileImg = $('#file')[0].files[0];
    
    let form = new FormData();

    form.append("keyA", new Blob([JSON.stringify(data)], {type: "application/json"}))
    form.append("keyB", fileImg);

    $.ajax({
        type: "POST",
        url: "/example",
        contentType: false,
        processData: false,
        data: form,
        success: function (response) {
            alert("SUCCESS!");
        }
    });
}
</script>

[의문점] 여기서 잠깐!
기존에 JSON 포맷을 ajax를 사용해 서버로 전송했는데 이때는 Content-Typeapplication/json으로 보내면 됐다. 하지만 파일까지 같이 보내면 Content-Typemultipart/form-data이다.
ajax로 두 가지 타입을 보낼 수 있나?? 그렇다고 파일을 JSON 안에 넣을 수는 없을테고...

의문점 해결

FormData를 만들고 FormData 객체에 JSON과 file을 append한다. 그리고 FormData 객체를 서버로 전송한다.

ajax로 두 가지 Content-Type을 보낼 수 없다. 그래서 Blob을 사용하여 Content-Type을 지정해서 FormData에 추가한다. 이는 여러 Content-Type으로 보낼 수 있게 한다.

data 파라미터로 전달된 데이터를 jQuery 내부적으로 쿼리 스트링으로 만드는데, 파일 전송의 경우에는 쿼리 스트링이 사용되지 않는다. 이를 설정하는 것이 processData: false다.

contentTypedefault 값이 "application/x-www-form-urlencoded; charset=UTF-8"인데, "multipart/form-data"로 전송 되게 false로 넣어준다.

알쓸신잡
IE 브라우저에서 ajax를 사용하다보면 데이터가 갱신이 안 되고 이전 데이터가 그대로 남아있는 경우가 있다. 이는 IE 브라우저에서 ajax 통신을 할 때 url을 새로 호출하지 않고, 가지고 있는 캐시 값을 그대로 노출시킨다. 따라서 cache: false를 사용하여 캐싱을 막는다.

서버에서 FormData 받는 방법

@PostMapping("/example")
public Example example(@RequestPart(name = "keyA") ExampleDto exampleDto, @RequestPart(name = "keyB") MultipartFile multipartFile) throws IOException {
	return exampleService.postExample(exampleDto, multipartFile);
}

보통 Controller로 요청이 온 JSON을 DTO로 바인딩 할 때는 @RequestBody를 주로 사용한다.
그리고 File을 받을 때는 MultipartFile 객체를 사용하고 @RequestParam을 사용한다.

하지만 File과 Dto를 같이 받기 위해서@RequestPart라는 어노테이션을 사용한다.

비즈니스 로직은 Service 계층에서 처리한다.

참고
https://repacat.tistory.com/38

https://medium.com/jaehoon-techblog/simpleblog-%EA%B0%9C%EB%B0%9C-%EC%9D%BC%EC%A7%80-4-55a8d2a8604

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

0개의 댓글