데브포일 홈
WordPress 자동화
Guest
STAGE 13 · Lv.64

AJAX & REST API 엔드포인트

wp_ajax 액션, wp_localize_script, nonce 보안, register_rest_route, WP_REST_Response, 스키마 정의까지 WordPress의 비동기 통신을 완전 마스터합니다.

WordPress AJAX의 두 가지 방식

admin-ajax.php vs REST API

WordPress에서 비동기 통신을 구현하는 방법은 크게 두 가지입니다. 전통적인 admin-ajax.php 방식과 현대적인 REST API 방식입니다. 둘 다 여전히 유효하며, 상황에 따라 적절한 방식을 선택합니다.


admin-ajax.php: WordPress 초기부터 사용된 방식으로, wp-admin/admin-ajax.php 파일을 통해 AJAX 요청을 처리합니다. 구현이 간단하고 nonce 기반 보안이 내장되어 있습니다.


REST API: WordPress 4.7부터 코어에 포함된 방식으로, RESTful 원칙을 따릅니다. URL 구조가 명확하고, JSON 기반이며, 외부 서비스와의 통합에 유리합니다.

비교 항목 admin-ajax.php REST API
URL 구조 admin-ajax.php?action=xxx /wp-json/namespace/route
HTTP 메서드 주로 POST GET, POST, PUT, DELETE
인증 Nonce 기반 Nonce, Cookie, OAuth, App Password
캐싱 어려움 HTTP 캐싱 가능
외부 접근 제한적 완전 지원
권장 사용처 관리자 내부 기능 프론트엔드, 모바일 앱, 외부 연동

admin-ajax.php 방식 구현

단계별 구현 가이드

admin-ajax.php 방식은 3단계로 구현합니다: ① JavaScript에서 AJAX 요청 전송, ② PHP에서 요청 처리, ③ nonce를 이용한 보안 처리.

1
PHP: 스크립트 등록 및 localize - AJAX URL과 nonce를 JavaScript에 전달
2
JavaScript: AJAX 요청 전송 - fetch 또는 jQuery.ajax로 요청
3
PHP: AJAX 핸들러 - nonce 검증 후 데이터 처리 및 응답
// ========== 1단계: 스크립트 등록 및 데이터 전달 ========== add_action('wp_enqueue_scripts', function() { wp_enqueue_script( 'map-ajax', MAP_PLUGIN_URL . 'public/js/ajax.js', ['jquery'], MAP_VERSION, true ); // JavaScript에서 접근 가능한 데이터 전달 wp_localize_script('map-ajax', 'mapAjax', [ 'url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('map_ajax_nonce'), ]); });
// ========== 2단계: JavaScript AJAX 요청 ========== // public/js/ajax.js // 방법 1: Fetch API (권장) async function loadPosts(page = 1) { const formData = new FormData(); formData.append('action', 'map_load_posts'); formData.append('nonce', mapAjax.nonce); formData.append('page', page); try { const response = await fetch(mapAjax.url, { method: 'POST', body: formData, }); const data = await response.json(); if (data.success) { document.getElementById('posts-container').innerHTML = data.data.html; } else { alert(data.data.message || '오류가 발생했습니다.'); } } catch (error) { console.error('AJAX 오류:', error); } } // 방법 2: jQuery (레거시) jQuery(function($) { $('#load-more').on('click', function() { $.ajax({ url: mapAjax.url, type: 'POST', data: { action: 'map_load_posts', nonce: mapAjax.nonce, page: 2 }, success: function(response) { if (response.success) { $('#posts-container').append(response.data.html); } } }); }); });
// ========== 3단계: PHP AJAX 핸들러 ========== // 로그인 사용자용 + 비로그인 사용자용 모두 등록 add_action('wp_ajax_map_load_posts', 'map_ajax_load_posts'); add_action('wp_ajax_nopriv_map_load_posts', 'map_ajax_load_posts'); function map_ajax_load_posts() { // 1. Nonce 검증 if (!check_ajax_referer('map_ajax_nonce', 'nonce', false)) { wp_send_json_error(['message' => '보안 검증 실패'], 403); } // 2. 입력값 정리 $page = absint($_POST['page'] ?? 1); // 3. 데이터 조회 $query = new WP_Query([ 'post_type' => 'post', 'posts_per_page' => 6, 'paged' => $page, ]); if (!$query->have_posts()) { wp_send_json_error(['message' => '더 이상 글이 없습니다.']); } // 4. HTML 생성 ob_start(); while ($query->have_posts()) { $query->the_post(); echo '<div class="post-card">'; echo '<h3>' . get_the_title() . '</h3>'; echo '<p>' . get_the_excerpt() . '</p>'; echo '</div>'; } $html = ob_get_clean(); wp_reset_postdata(); // 5. 성공 응답 wp_send_json_success([ 'html' => $html, 'total_pages' => $query->max_num_pages, 'current' => $page, ]); }
AJAX 보안 체크리스트
1. Nonce 검증: 모든 AJAX 요청에서 nonce를 검증하세요. CSRF 공격을 방지합니다.

2. 권한 체크: 관리자 전용 기능이라면 current_user_can()으로 권한을 확인하세요.

3. 입력값 정화: $_POST, $_GET 값을 절대 그대로 사용하지 마세요. sanitize_* 함수로 정화합니다.

4. wp_ajax_nopriv: 비로그인 사용자에게 필요한 경우에만 등록하세요. 관리 기능은 wp_ajax_만 사용합니다.
🔒
여기까지는 미리보기입니다
AJAX & REST API 엔드포인트
무료 가입하면 이어서 볼 수 있고, 강의를 완료할 때마다 XP와 레벨이 쌓입니다.
Google로 3초 만에 시작 →🧵 Threads로 시작무료 공개 강의 둘러보기 (Lv.1~3)