![[JS] 11. CSR(Client-Side-Rendering)](https://image.inblog.dev?url=https%3A%2F%2Finblog.ai%2Fapi%2Fog%3Ftitle%3D%255BJS%255D%252011.%2520CSR%28Client-Side-Rendering%29%26logoUrl%3Dhttps%253A%252F%252Finblog.ai%252Finblog_logo.png%26blogTitle%3Djjack1&w=2048&q=75)
1. 메인 페이지 렌더링

코드
{{> 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="delBoard(${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 boardBox = document.querySelector("#board-box");
boardList.forEach((board) => {
boardBox.append(makeBoard(board));
});
}
init();
</script>
{{> layout/footer}}
2. 수정 페이지 렌더링


코드
{{> layout/header}}
<div class="container p-5">
<div class="card">
<div class="card-header"><b>익명 글수정 화면입니다</b></div>
<div class="card-body">
<form action="#">
<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="submit" class="btn btn-primary form-control">글수정완료</button>
</form>
</div>
</div>
</div>
<script>
let boardId = document.querySelector("#boardId").value; // html에 있는 id가져오는 방법
let boardId2 = getCookie("boardId"); // 쿠키에서 id가져오는 방법
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 반환
}
// 책임: 통신
async function init() {
let response = await fetch("/api/boards/" + boardId);
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;
}
init();
</script>
{{> layout/footer}}
수정 페이지를 렌더링 하기 위해선 이 페이지의 id값이 필요하다
id를 가져오는 방법은 2가지가 있다
- HTML 안에 숨은 input 태그를 만들고 거기에 id를 넣어 보내는 것 (서버가 input에 id를 넣어줌)
- 쿠키에 있는 값을 읽어서 사용 (서버가 쿠키에 id를 넣어줌)
- 자바스크립트로 쿠키의 값을 읽는 방식은 보안에 위험함으로 httpOnly를 사용해 자바스크립트에서 접근하지 못하게 막음

httpOnly는 http프로토콜에 의한 쿠키 읽음만 가능함. 브라우저와 서버만 접근 가능
서버에서 쿠키를 주는 방법
@GetMapping("/board/{id}/updateForm")
public String updateForm(
@PathVariable int id,
HttpServletRequest request,
HttpServletResponse response) {
request.setAttribute("boardId", id);
Cookie cookie = new Cookie("boardId", id + "");
cookie.setHttpOnly(true); // http프로토콜 전용으로 사용해라 js가 접근 불가, 브라우저의 통신에서만 접근 허용
response.addCookie(cookie);
return "board/updateForm";
}
3. post로 데이터 insert하기


코드
{{> 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>
// 아래 함수 작성하기 전에,
// 1. button -> type button으로!!
// 2. input name을 id로 변경하기
async function writeBoard() {
// 1. id 값 찾아서 requestBody 오브젝트에 넣기
let requestBody = {
title: document.querySelector("#title").value,
content: document.querySelector("#content").value,
author: document.querySelector("#author").value
}
// 2. fetch post 요청하기
let response = await fetch("/api/boards", {
method: "post",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(requestBody)
})
let responseBody = await response.json();
console.log(responseBody);
// 3. 마지막에 아래 코드로 페이지 이동하기
location.href = "/";
}
</script>
{{> layout/footer}}
4. put으로 update하기



코드
{{> layout/header}}
<div class="container p-5">
<div class="card">
<div class="card-header"><b>익명 글수정 화면입니다</b></div>
<div class="card-body">
<form action="#">
<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="put1()" class="btn btn-primary form-control">글수정완료</button>
</form>
</div>
</div>
</div>
<script>
let boardId = document.querySelector("#boardId").value; // html에 있는 id가져오는 방법
let boardId2 = getCookie("boardId"); // 쿠키에서 id가져오는 방법
let inputAuthor = document.querySelector("#author");
let inputTitle = document.querySelector("#title");
let inputContent = document.querySelector("#content");
// 책임: 통신
async function put1() {
let requestBody = {
author: inputAuthor.value,
title: inputTitle.value,
content: inputContent.value
}
let response = await fetch("/api/boards/" + boardId, {
method: "put",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(requestBody)
});
let responseBody = await response.json();
location.href = "/"
}
// 쿠키에서 key에 대한 값 리턴
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 반환
}
// 책임: 통신
async function init() {
let response = await fetch("/api/boards/" + boardId);
let responseBody = await response.json();
inputAuthor.value = responseBody.body.author;
inputTitle.value = responseBody.body.title;
inputContent.value = responseBody.body.content;
}
init();
</script>
{{> layout/footer}}
4. delete로 delete하기


코드
{{> 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.setAttribute("id", `board-${board.id}`);
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 type="button" class="btn btn-danger" onclick="delBoard(${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 delBoard(boardId) {
let response = await fetch("/api/boards/" + boardId, {
method: "delete"
});
let responseBody = await response.json();
console.log(responseBody)
// location.reload(); // 페이지 새로고침
let tr = document.querySelector(`#board-${boardId}`);
tr.remove();
}
// 책임: 통신
async function init() {
let response = await fetch("/api/boards");
let responseBody = await response.json();
let boardList = responseBody.body;
// console.log(boardList);
let boardBox = document.querySelector("#board-box");
boardList.forEach((board) => {
boardBox.append(makeBoard(board));
});
}
init();
</script>
{{> layout/footer}}
Share article