이전 포스팅에서 통신을 비동기로 처리하기 위해 fetch api 와 async / await 을 이용했었다
다른 방법으로는 자바스크립트의 ajax를 이용할 수가 있다
ajax 는 순수 자바스크립트로 작성하는것보다 제이쿼리로 작성하는것이 더 쉽다
이번에는 ajax 를 이용한 비동기 통신에 대해 알아보자
브라우저가 요청을 하면 서버에서 응답 ( html, css, js, 서버사이드 프로그램등 ) 을 한다
Ajax 는 JS를 이용하여 비동기적으로 서버와 데이터를 주고 받는다
화면의 일부만을 갱신해서 동적인 페이지를 만들어주는데 예를들어 페이스북, 인스타그램등의 스크롤을 떠올리면 된다
우선적으로 ajax 또한 제이쿼리의 기능이므로 cdn을 먼저 추가해야한다
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
작업의 효율성을 위해서 스니펫을 만들었다
{
"Ajax Template": {
"prefix": "aj",
"body": [
"$.ajax({",
" type: \"$1\",",
" url: \"/\",",
" data: JSON.stringify(),",
" headers:{",
" \"content-type\":\"application/json; charset=utf-8\"",
" },",
" dataType:\"json\"",
"}).done((res) => {",
"",
"}).fail((err) => {",
"",
"});"
],
"description": "Ajax Template"
}
}
Ajex 를 이용해서 get, post, put, delete 요청을 해보자
<body>
<h1>ajax get 요청</h1><hr>
<button onclick="getPost()">통신요청</button>
<script>
function getPost(){
$.ajax({
type:"get", // fetch의 method 기능
url: "http://localhost:8080/init/post", // json 넣어놨음
dataType:"json"
// 메타데이터 타입을 명시해주면, ajax가 자동으로 js오브젝트로 파싱해준다
// 성공
}).done((abc)=>{
console.log(abc);
if(abc.code == 1){
alert('통신성공');
}
})
// 실패
.fail((err)=>{
console.log(err);
}); // 실패시 - 상태코드 200 아닐때 // done + fail 은 콜백
}
</script>
</body>
ajax
는 promise.then
문법을 사용한다
( fetch 도 async/await 대신에 .then 가능 )
$.ajax({})
가 fetch api 의 기능을 수행하고 .then
이 ( 여기서는 done()
,fail()
) ajax의 처리가 끝나면 콜백함수를 실행한다
.done()
의 파라미터는 파싱된 js오브젝트로 인식된다
.fail()
은 상태코드가 200이 아닐때 실행된다
dataType:"json"
으로 설정해서 json 에 넣은 code를 읽을 수가 있다. ( 여기서 code 는 프론트와 백엔드 사이에서 만든 프로토콜 )
dataType:"text"
라면 abc.code
는 읽지 못한다
브라우저를 살펴보자
받은 데이터를 화면에 렌더링 해보자
function getPost(){
$.ajax({
type:"get",
url: "http://localhost:8080/init/post",
dataType:"json"
}).done((abc)=>{
if(abc.code == 1){
render(abc.data);
}else{
alert('통신실패');
}
})
.fail((err)=>{
console.log(err);
});
}
function render(posts){
posts.forEach((post)=>{
let el = `
<div id="post-${post.id}">
${post.id} ${post.title} ${post.content}
</div>
<button id="btnDelete-${post.id}">삭제</button>
`;
$("#postBox").prepend(el);
})
}
만약에 삭제를 하고 싶다면 ?
이렇게 버튼의 아이디를 id="btnDelete-${post.id}"
로 만들면 id를 전부 달아야 하고 찾아야 하므로 너무 귀찮아진다
좀 더 편한 방법이 필요하다
리스너 등록해서 삭제하자
function render(posts) {
posts.forEach((post) => {
let el = `
<div id="post${post.id}">
${post.id} ${post.title} ${post.content}
</div>
<buttontoken interpolation">${post.id})"> 삭제 </button>
`;
$("#postBox").prepend(el);
})
}
function deleteById(id) {
$(event.currentTarget).remove();
$(`#post${id}`).remove();
}
이벤트 객체를 이용하면 event.currentTarget
로 누른버튼까지 삭제할 수 있다
이렇게 html 을 자바스크립트로 제어를 하고 싶다면 id를 달아 놓아야 한다
제이쿼리만 이용해서 화면에서만 데이터를 삭제했는데 ajax를 이용해서 비동기적인 삭제요청을 보내 삭제하는 방법은 아래의 Delete요청에서 다룬다
지금부터는 https://jsonplaceholder.typicode.com/ 를 이용해서 연습을 해보자
( 서버는 중요하지 않음 )
<form>
<input type="text" id="title" placeholder="Enter title"><br>
<input type="text" id="body" placeholder="Enter body"><br>
<input type="text" id="userId" placeholder="Enter userId"> <br>
<button type="button" onclick="write1()">글쓰기</button>
</form>
폼 전송을 사용하지 않고 ajax 를 사용하기 위해 form태그의 action
을 지웠다
버튼 태그의 디폴트 타입은 submit
이다.
타입이 submit
일때 input에 내용을 작성하고 버튼을 누르면 action
이 없어 데이터를 보내지는 않지만 새로고침이 되어 input 의 내용이 사라진다.
버튼 타입을 button
으로 설정하게 되면 input 태그의 내용이 사라지지 않는다.
<script>
function write1(){
let post = {
title: $(`#title`).val(), // 3가지 가능
body: $('#body').val(),
userId: $("#userId").val()
};
$.ajax({
type:"post",
url: "https://jsonplaceholder.typicode.com/posts",
data:JSON.stringify(post), // js오브젝트를 json으로 파싱
headers:{
"content-type":"application/json; charset=utf-8"
},
dataType:"json"
}).done((res)=>{
console.log('id',res.id);
console.log('title',res.title);
console.log('body',res.body);
console.log('userId',res.userId);
}).fail((err)=>{
console.log(err);
});
}
</script>
put 으로 데이터를 수정할 수 있다
이번에는 처음부터 서버에서 데이터를 가져와 수정을 해보자
<form>
<input type="text" id="number1" placeholder="입력">
<button type="button" onclick="onLoad()">데이터 불러오기</button>
<div id="here">
</div>
<button type="button" onclick="updateById()">수정하기</button>
</form>
div태그를 만들어 가져올 데이터가 들어올 박스를 두었다.
<script>
function onLoad() {
$('#here').empty();
let num = $('#number1').val();
$.ajax({
type: "get",
url: `https://jsonplaceholder.typicode.com/posts/${num}`,
dataType: "json"
}).done((post) => {
render(post);
}).fail((err) => {
console.log(err);
});
}
function render(post){
$("#here").append(`
<input type="text" id="id" id="id" value="${post.id}"><br>
<input type="text" size="50" id="title" value="${post.title}"><br>
<input type="text" size="50" id="body" value="${post.body}"><br>
<input type="text" id="userId" value="${post.userId}"><br>
`)
}
function updateById() {
let post = {
id: $('#id').val(),
title: $('#title').val(),
body: $('#body').val(),
userId: $('#userId').val()
};
console.log(JSON.stringify(post));
$.ajax({
type: "put",
url: `https://jsonplaceholder.typicode.com/posts/${post.id}`,
data: JSON.stringify(post),
headers: {
"content-type": "application/json; charset=utf-8"
},
dataType: "json"
}).done((res) => {
alert('성공')
console.log('id', res.id);
console.log('title', res.title);
console.log('body', res.body);
console.log('userId', res.userId);
}).fail((err) => {
console.log(err);
});
}
</script>
onLoad()
는 위에서 했던 get요청과 같다
입력한 숫자에 맞는 데이터를 가져와서 $("#here").append
로 만들어둔 div태그에 추가해준다.
위에서 제이쿼리만 이용해서 삭제를 했지만 정상적으로 삭제를 하려면 서버에 삭제요청까지 보내야 한다
<form>
<input type="text" id="id" placeholder="Enter id">
<button type="button" onclick="updateById()">삭제하기</button>
</form>
<script>
function updateById(){
// 1. 사용자 값 받아오기
let id = $('#id').val();
// 2. 유효성 검사
if( id == "undefined" || id == ""){
alert('삭제할 아이디를 입력하세요')
return;
}
// 3. 통신하기
$.ajax({
type:"delete",
url: `https://jsonplaceholder.typicode.com/posts/${id}`
}).done(()=>{
alert('성공')
// location.href="삭제하고 이동할 주소"
console.log(id);
}).fail(()=>{
console.log('에러');
});
}
</script>
1차적으로 입력이 유효한지 검증한후 요청을 보내면 된다