AJAX 방식으로 서버에 직접 form을 전송하는 방법에 대해 정리해보겠습니다.
Form에 포함된 파일이나 이미지 등을 서버로 간단하게 전송할 수 있습니다.
fetch API를 통해 데이터를 전송할 때, FormData 객체를 생성하여 전달하면 form을 전달할 수 있습니다.
var data = new FormData(form) 과 같이 form을 읽어서 FormData를 생성하면 됩니다.
혹은 FormData 객체에 파일 등을 직접 append 하는 방식으로도 파일을 담을 수 있습니다.
Fetch API를 이용하여 댓글을 작성하는 예시를 살펴보겠습니다.
function uploadComment(form){
var data = new FormData(form);
fetch(
'/comments/upload',
{
method : 'POST',
body : data,
}
)
.then((response) =>
{
loadComments();
}
)
}
클라이언트에서는 form 자체를 통해 FormData를 생성한 후 body를 통해 전달해주면 됩니다.
@ResponseBody
@PostMapping("/comments/upload")
public void comment(CommentForm commentForm){
// CommentForm에 담긴 정보로 처리
}
실제 댓글을 등록하는 코드는 생략하였습니다.
클라이언트에서 전송하는 form 안의 elements의 name 필드와 파라미터의 CommentForm 변수명으로 매핑되어 서버에서 form안의 값들을 사용할 수 있습니다.
<input id = "files" type="file" multiple onchange="uploadPhoto(this)" hidden>
파일을 선택하면 uploadPhoto에 this를 전달하며 호출합니다.
function uploadPhoto(obj){
for(const file of obj.files){
(function(file) {
var formData = new FormData();
formData.append("photo", file);
fetch(
'/photos/upload',
{
method : 'POST',
body : formData
}
)
.then((response) => {
// ...
})
formData에 직접 file을 추가한 후, fetch의 body에 formData를 담아주면 됩니다.
@PostMapping("photos/upload")
@ResponseBody
public String uploadPhoto(MultipartFile photo) throws IOException {
File file = new File(/*저장할 위치, 파일 정보*/);
photo.transferTo(file);
}
파일을 저장하는 코드만 남겨두었습니다.
Controller에서는 MultiparFile로 파일을 받을 수 있습니다.