[jQuery] $.ajax() 사용하기
0. jQuery의 $.ajax()
jQuery에서 제공하는 $.ajax()를 사용하면 기존의 XMLHttpRequest보다 비교적 편리하게 AJAX를 사용할 수 있다.
$.ajax({
url: '요청 URL',
type: '요청 방식',
data: '요청 데이터',
dataType: '요청 후 return하는 데이터의 타입',
async: '동기/비동기',
timeout: '요청 후 제한시간',
beforeSend: '요청 전 발생하는 이벤트 핸들러',
success: '요청 성공 시 이벤트 핸들러',
error: '요청 실패 시 이벤트 핸들러',
complete: '요청 완료 시 이벤트 핸들러'
});
1. get 요청
$.ajax()를 사용해 get 요청을 경우 type을 'get'으로 설정하면 된다. 서버에 보내고 싶은 데이터가 있을 경우 url의 뒤에 직접 쿼리스트링으로 작성해도 되고, data에 자바스크립트 객체를 작성해도 된다.
$.ajax({
url: '/test?testNum=123',
type: 'get',
data: {
'testData1' : 'data1',
'testData2' : 'data2'
},
success: function(result){
console.log(result);
}
});
스프링 프레임워크에서는 위와 같은 방법으로 들어온 요청 데이터를 @RequestParam 어노테이션으로 받을 수 있다. jQuery의 ajax의 경우 data에 설정된 값을 쿼리스트링으로 변환해주기 때문이다.
다만 VO 객체로 받을 때는 @ModelAttribute 어노테이션을 사용한다. VO 객체 내에 쿼리스트링의 key와 일치하는 이름의 멤버변수가 VO 클래스에 선언되어있어야 한다.
@ResponseBody
@GetMapping("/test")
public String test(@RequestParam String testNum,
@RequestParam String testDate1,
@RequestParam String testData2,
@RequestParam Map<String, String> data,
@ModelAttribute TestVO testVO){
System.out.println("testNum : " + testNum);
System.out.println("testData1 : " + testData1);
System.out.println("testData2 : " + testData2);
System.out.println("dataMap : " + data);
System.out.println("testVO : " + testVO);
return "SUCCESS";
}
2. post 요청
요청방식이 post일 경우에는 type에 'post'를 적어준다. 쿼리스트링은 사용할 수 없고 data에 작성하는 값을 JSON.stringify()로 변환하는 등의 추가적인 처리가 필요하다.
JSON.stringify()를 사용할 경우 Content-Type을 설정해야한다. $.ajax()에서 제공하는 'contentType'이라는 옵션에 작성하여도 되고, beforeSend에서 setRequestHeader()를 통해 직접 헤더에 작성해주어도 된다.
또한 스프링 시큐리티를 사용할 경우 post 방식에서는 csrf 토큰을 요청 헤더에 포함시켜야 한다.
$.ajax({
url: '/test',
type: 'post',
dataType: 'text',
data: JSON.stringify({
'testNum' : '123',
'testData1' : 'data1',
'testData2' : 'data2'
}),
contentType: 'application/json;charset=utf-8',
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-TOKEN', '${_csrf.token}');
},
success: function(result){
console.log(result);
}
});
위처럼 JSON.stringify()를 사용해 데이터를 전송할 경우 서버에서는 @RequestBody를 사용해 데이터를 받아야한다. 데이터는 Map 객체나 VO 객체로 받을 수 있다.
@ResponseBody
@PostMapping("/test")
public String test(@RequestBody Map<String, String> data,
@RequestBody TestVO testVO){
System.out.println("dataMap : " + data);
System.out.println("testVO : " + testVO);
return "SUCCESS";
}
* FormData의 전송
자바스크립트의 객체인FormData 객체는 multipart/form-data로 분류된다. 이를 요청데이터로 보내기 위해서는 contentType과 processData를 false로 설정해야한다.
contentType을 false로 설정할 경우 Content-Type은 'multipart/form-data'로 설정된다.
processData의 경우 data에 작성된 값을 쿼리스트링으로 처리할지 여부를 결정하는 항목이다. 이를 false로 설정하여 쿼리스트링으로 처리되지 않도록 한다.
let formData = new FormData();
formData.append('testData1', 'data1');
formData.append('testData2', 'data2');
$.ajax({
url: '/test',
type: 'post',
dataType: 'text',
contentType: false,
processData: false,
data: formData,
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-TOKEN', '${_csrf.token}');
},
success: function(result){
console.log(result);
}
});
위의 경우에는 Map이나 기본 타입에는 @RequestParam 어노테이션을, VO 객체에는 @ModelAttribute 어노테이션을 사용하여 데이터를 받으면 된다.
@ResponseBody
@GetMapping("/test")
public String test(@RequestParam String testDate1,
@RequestParam String testData2,
@RequestParam Map<String, String> data,
@ModelAttribute TestVO testVO){
System.out.println("testData1 : " + testData1);
System.out.println("testData2 : " + testData2);
System.out.println("dataMap : " + data);
System.out.println("testVO : " + testVO);
return "SUCCESS";
}
3. 정리
방식 | 데이터 타입 | 데이터 | 어노테이션 | 타입 |
GET | String | 쿼리스트링 또는 자바스크립트 객체를 그대로 작성 | @RequestParam | 기본 타입, Map |
@ModelAttribute | VO 클래스 | |||
POST | JSON | 객체를 JSON.stringify()로 감싸서 작성 | @RequestBody | 기본 타입, Map, VO 클래스 |
FormData | FormData 객체를 그대로 작성 | @RequestParam | 기본 타입, Map | |
@ModelAttribte | VO 클래스 |