[자바스크립트] 9. Request with JSON

문정준's avatar
Apr 02, 2025
[자바스크립트] 9. Request with JSON

1. ajax-blog 예제 clone

 

2. Get

1. index.mustache

{{> layout/header}} <div class="container p-5"> <table class="table table-striped"> <thead> <tr> <th>번호</th> <th>제목</th> <th>내용</th> <th>작성자</th> <th></th> </tr> </thead> <tbody id="board-box"> </tbody> </table> </div> <script> // 책임 : 컴포넌트 하나 생성 function makeBoard(board) { let tr = document.createElement("tr"); tr.innerHTML = `<td>${board.id}</td> <td>${board.title}</td> <td>${board.content}</td> <td>${board.author}</td> <td> <div class="d-flex"> <form action="#"> <button class="btn btn-danger" onclick="deleteBoard(${board.id})">삭제</button> </form> <form action="/board/${board.id}/updateForm" method="get"> <button class="btn btn-warning">수정</button> </form> </div> </td>`; return tr; } // 책임 : 통신 async function init() { let response = await fetch("/api/boards"); let responseBody = await response.json(); let boardList = responseBody.body; // console.log(boardList); let tbody = document.querySelector("#board-box"); boardList.forEach((board)=>{ tbody.append(makeBoard(board)); }); } init(); </script> {{> layout/footer}}
 
  • 기존의 방식 : request를 통해 서버 측에서 데이터를 리스트로 받은 후, 이를 직접 화면에 뿌림
    • SSR ( Server-Side Rendering )
      • 요청이 많아지면 서버에 부하가 많이 갈 수 있음
      • 이를 대처하기 위해 나온 방법이 CSR ( Client-Side Rendering )
 
  • 새로운 방식 : 서버에서는 HTML 양식만 뿌리고, JavaScript에서 fetch를 통해 데이터를 다운
    • 그 데이터를 body에 담아 브라우저가 Rendering
      • 서버는 HTML과 데이터만 전송하고, 나머지는 클라이언트(Browser)에서 Rendering
 
notion image
 
 
 

2. Put

  • 업데이트 화면만 보았을 때에, 해당 글의 정보를 담아올 수 있는 방법이 있을까?
    • 3가지의 방법이 존재
        1. SSR : 서버에서 id를 model에 담아서 전송
        1. Parse URL : 주소에 적힌 8을 파싱하여 구하기
        1. Use Cookie : 서버 측에서 id의 정보를 쿠키에 담아서 활용 ( 👍 )
notion image
 
 

1. BoardController.java

@GetMapping("/board/{id}/updateForm") public String updateForm(@PathVariable int id, HttpServletRequest request, HttpServletResponse response) { // 1. ssr : template engine request.setAttribute("boardId", id); // 2. cookie Cookie cookie = new Cookie("boardId", id+""); // cookie.setHttpOnly(true); response.addCookie(cookie); // 응답의 헤더 -> Set-Cookie : boardId=5 return "board/updateForm"; }
  • request (model) 활용 : SSR ( Server-Side Rendering )
    • 간단한 객체일 경우 이를 활용해도 상관 없음
  • Cookie 추가 : Cookie 객체를 만들어서 응답 객체에 쿠키를 추가
    • setHeader(”Set-Cookie”,”boardId=”+id) ← 기존의 쿠키를 삭제시켜버림
    • 기존에 들고 있던 쿠키를 가지고 가기 위해서는 이전 값을 더해서 새로 저장해야 함
    • 이를 대체하기 위해 addCookie() 사용
 

2. updateForm.mustache

{{> layout/header}} <div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글수정 화면입니다</b></div> <div class="card-body"> <form> <input type="hidden" id="boardId" value="{{boardId}}"> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content"></textarea> </div> <button type="button" onclick="updateBoard()" class="btn btn-primary form-control">글수정완료</button> </form> </div> </div> </div> <script> let boardId = document.querySelector("#boardId").value; let boardId2 = getCookie("boardId"); // 책임 : 통신 async function init() { console.log(boardId2); let response = await fetch("/api/boards/"+boardId2); let responseBody = await response.json(); document.querySelector("#author").value = responseBody.body.author; document.querySelector("#title").value = responseBody.body.title; document.querySelector("#content").value = responseBody.body.content; } function getCookie(key) { const cookies = document.cookie.split('; '); for (let cookie of cookies) { const [k, v] = cookie.split('='); if (k == key) { return v; } } return null; // 해당 키가 없으면 null 반환 } init(); async function updateBoard() { let requestBody = { author:document.querySelector("#author").value, title:document.querySelector("#title").value, content:document.querySelector("#content").value }; let postResponse = await fetch("/api/boards/"+boardId2, { method:"put", body:JSON.stringify(requestBody), headers:{"Content-Type" : "application/json"} }); let postResponseBody = await postResponse.json(); console.log(postResponseBody); location.href = "/"; } </script> {{> layout/footer}}
  • boardId = template engine을 통해 입력받은 input의 value를 통해 id를 전달받음
  • boardId2 = 브라우저의 cookie 정보를 파싱하여 key가 일치하는 cookie 값을 id로 전달받음
 
✏️

CSR을 무조건 사용해야 하나요?

서버에서 자원을 과도하게 사용하지 않는다면, 서버 측에서 Rendering을 하여 Client에게 HTML을 제공하여도 문제는 없습니다. 페이지 내에 Rendering이 필요한 요소가 많을 경우에 보통 CSR을 사용합니다. 서버의 비즈니스를 파악하여 목적에 맞게 사용하는 것이 중요합니다.
 
 

3. Post

1. saveForm.mustache

{{> layout/header}} <div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글쓰기 화면입니다</b></div> <div class="card-body"> <form action="#"> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content"></textarea> </div> <button type="button" onclick="writeBoard()" class="btn btn-primary form-control">글쓰기완료</button> </form> </div> </div> </div> <script> async function writeBoard() { let requestBody = { author:document.querySelector("#author").value, title:document.querySelector("#title").value, content:document.querySelector("#content").value }; let postResponse = await fetch("/api/boards", { method:"post", body:JSON.stringify(requestBody), headers:{"Content-Type" : "application/json"} }); let postResponseBody = await postResponse.json(); console.log(postResponseBody); location.href = "/"; } </script> {{> layout/footer}}
 
✏️

form 태그 내에 button이 submit이 아닌 이유

  • form 태그 내의 button type의 submit은 form의 action을 작동, 기본 method는 get
  • 특정 이벤트를 발생시켜서 요청을 발생시킬 경우, script 내의 function을 발동시켜야 함
  • function을 발동시키기 위해서는 onclick 이벤트를 수행해야 함
  • type이 submit일 경우 onclick 이벤트를 스킵 → form action을 우선 수행
  • onclick 이벤트를 수행하기 위해서는 button type을 button으로 변경해야 함
 

4. Delete

1. index.mustache

async function deleteBoard(id) { let response = await fetch("api/boards/" + id, { method:"DELETE" }); let responseBody = await response.json(); console.log(responseBody); location.reload(); }
  • 폼 태그 내의 id 값을 전달받아 해당 게시물 삭제
Share article

sxias