게시판 사이트에 핵심인 글 삭제 기능을 개발하기로 했다.
onclick -> deletePost(id)
실행, fetch
로 DELETE /posts/{id}
로 http 요청 전송SessionUser
. id
를 Service 계층으로 전송Service 계층
findByIdWithUser(postId)
로 Post + User 를 fetch join
으로 로딩PostNotFoundException
PostAccessDeniedException
ResponseEntity
리턴 ( 2xx 응답 반환(바디 없음))res.ok
를 확인해 window.location.assign('/')
로 홈 이동. <!-- 삭제 버튼 (작성자만 보이게)-->
<button th:if ="${session.user != null and session.user.id == post.userId}"
type ="button" class="btn-delete"
th:onclick="|deletePost(${post.postId})|">삭제</button>
async function deletePost(id) {
if (!confirm('정말 삭제하시겠습니까?')) return;
const token = document.querySelector('meta[name="_csrf"]')?.content;
const header = document.querySelector('meta[name="_csrf_header"]')?.content || 'X-CSRF-TOKEN';
const res = await fetch(`/posts/${id}`, {
method: 'DELETE',
headers: token ? { [header]: token, 'X-Requested-With': 'XMLHttpRequest' } : { 'X-Requested-With': 'XMLHttpRequest' }
});
if (res.ok) {
window.location.assign('/'); // ← 여기서 직접 이동
} else {
alert('삭제에 실패했습니다.');
}
confirm()
함수를 사용해 "정말 삭제하시겠습니까?"라는 확인창을 띄운다. 사용자가 '취소'를 누르면 함수가 즉시 종료되어 아무 일도 일어나지 않는다.
<meta>
태그에 저장된 CSRF(Cross-Site Request Forgery) 토큰 정보를 읽어온다. 이 토큰은 서버로 요청을 보낼 때 HTTP 헤더에 담아 전송하며, 정상적인 경로로 요청이 왔음을 인증하는 역할을 한다.fetch
API를 사용해 지정된 URL (/posts/{id}
)로 DELETE
메서드 요청을 비동기적으로 보낸다. 이때, 앞서 준비한 CSRF 토큰과 AJAX 요청임을 알리는 헤더 정보를 함께 전송한다.res.ok
): 서버가 성공적으로 게시글을 삭제하고 정상 응답(HTTP 2xx)을 보내면, window.location.assign('/')
코드를 통해 사용자를 메인 페이지로 이동시킨다.