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

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

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로 전달받음
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}}
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