[JS] AJAX를 이용한 비동기 통신

merci·2023년 2월 1일
0

JavaScript

목록 보기
7/15
post-custom-banner

이전 포스팅에서 통신을 비동기로 처리하기 위해 fetch api 와 async / await 을 이용했었다
다른 방법으로는 자바스크립트의 ajax를 이용할 수가 있다
ajax 는 순수 자바스크립트로 작성하는것보다 제이쿼리로 작성하는것이 더 쉽다
이번에는 ajax 를 이용한 비동기 통신에 대해 알아보자



Ajax (Asynchronous JavaScript and XML)

브라우저가 요청을 하면 서버에서 응답 ( 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 요청을 해보자

Ajex의 get요청

<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>
  • ajaxpromise.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 는 읽지 못한다


브라우저를 살펴보자


  • 통신요청 버튼을 누르면 json으로 응답




받은 데이터를 화면에 렌더링 해보자

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 로 누른버튼까지 삭제할 수 있다

  • 1번과 2번을 삭제한 결과

이렇게 html 을 자바스크립트로 제어를 하고 싶다면 id를 달아 놓아야 한다

제이쿼리만 이용해서 화면에서만 데이터를 삭제했는데 ajax를 이용해서 비동기적인 삭제요청을 보내 삭제하는 방법은 아래의 Delete요청에서 다룬다


Ajex의 post요청

지금부터는 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>
  • 글쓰기를 누르면 비동기 요청이 된다( 내 서버가 아니라 콘솔에서 확인 )


Ajex의 put요청

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태그에 추가해준다.

  • 55번 데이터를 불러오면
  • 다음과 같이 수정하면
  • 아래와 같이 콘솔에 출력이 된다 ( 리소스 수정은 권한이 없음 )


Ajex의 delele요청

위에서 제이쿼리만 이용해서 삭제를 했지만 정상적으로 삭제를 하려면 서버에 삭제요청까지 보내야 한다

<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차적으로 입력이 유효한지 검증한후 요청을 보내면 된다

profile
작은것부터
post-custom-banner

0개의 댓글