AJAX 처리

작성자: admin 작성일: 2025-07-08
Function Guide

AJAX 처리 함수들

클라이언트(브라우저)와 서버 간의 AJAX 통신을 처리하는 함수들입니다. 푸시 구독 관리, 알림 설정, VAPID 키 조회 등을 JSON 형태로 처리합니다.

handle_push_subscription()

브라우저에서 푸시 구독 등록 요청을 AJAX로 처리합니다. JSON 응답을 반환하고 함수 실행을 종료합니다.
function handle_push_subscription()

요청 형식

HTTP Method

요청 형식

HTTP Method

GET 또는 POST 메서드 모두 지원합니다. 추가 파라미터는 필요하지 않습니다.

응답 형식

성공 시 (200 OK)

{
  "success": true,
  "message": "성공",
  "data": {
    "vapid_public_key": "BGtFqB7V9OZFKv7yZj8r5z6KcGqKh..."
  }
}

실패 시 (404)

{
  "success": false,
  "message": "VAPID 공개키가 설정되지 않았습니다."
}

JavaScript 사용 예시

// VAPID 공개키 조회 후 푸시 구독
async function initializePushSubscription() {
  // 1. VAPID 공개키 가져오기
  const response = await fetch('/ajax/get_vapid_key.php');
  const result = await response.json();

  if (!result.success) {
    console.error('VAPID 키 조회 실패:', result.message);
    return;
  }

  // 2. VAPID 키로 푸시 구독
  const vapidKey = result.data.vapid_public_key;
  const registration = await navigator.serviceWorker.ready;

  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(vapidKey)
  });

  console.log('푸시 구독 완료', subscription);
}

// VAPID 키 형식 변환 함수
function urlBase64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  const base64 = (base64String + padding)
    .replace(/-/g, '+')
    .replace(/_/g, '/');
  const rawData = window.atob(base64);
  return new Uint8Array([...rawData].map(char => char.charCodeAt(0)));
}

사용자 설정 AJAX 함수들

사용자의 알림 설정과 기기 관리를 위한 AJAX 처리 함수들입니다.

handle_save_notification_settings()

사용자의 알림 설정과 기기별 설정을 저장합니다.

요청 본문 예시

{
  "message_notification": 1,
  "comment_notification": 1,
  "inquiry_notification": 0,
  "devices": [
    {"id": 1, "enabled": 1},
    {"id": 2, "enabled": 0}
  ]
}

handle_get_notification_settings()

현재 사용자의 알림 설정과 등록된 기기 목록을 조회합니다.

응답 예시

{
  "success": true,
  "message": "성공",
  "data": {
    "settings": {
      "message_notification": 1,
      "comment_notification": 1,
      "inquiry_notification": 1
    },
    "devices": [
      {
        "id": 1,
        "device_name": "Chrome on Windows",
        "device_icon": "????",
        "is_active": 1,
        "created_at": "2024-01-15 10:30:00"
      }
    ]
  }
}

handle_toggle_device_notification()

특정 기기의 알림을 활성화/비활성화합니다.

요청 본문 예시

{
  "device_id": 1,
  "is_active": 0
}

공통 응답 처리

모든 AJAX 함수는 send_json_response() 함수를 사용하여 일관된 JSON 형태로 응답합니다.

send_json_response()

function send_json_response($success, $message, $data = null, $http_code = 200)

표준 응답 구조

모든 AJAX 응답은 다음 구조를 따릅니다.
  • success (Boolean) - 처리 성공 여부
  • message (String) - 처리 결과 메시지
  • data (Mixed) - 추가 데이터 (선택사항)

공통 에러 코드

HTTP 코드 의미 발생 상황
200 성공 정상 처리 완료
400 잘못된 요청 필수 데이터 누락, 잘못된 형식
404 리소스 없음 VAPID 키 미설정, 데이터 없음
405 메서드 불허용 GET 요청이 필요한 곳에 POST 요청
500 서버 오류 데이터베이스 오류, 내부 처리 실패

실제 구현 예시

완전한 푸시 알림 시스템 구축

// 1. 페이지 로드 시 초기화
document.addEventListener('DOMContentLoaded', async function() {
  if ('serviceWorker' in navigator && 'PushManager' in window) {
    await initializePushSystem();
  }
});

async function initializePushSystem() {
  // Service Worker 등록
  await navigator.serviceWorker.register('/sw.js');

  // 현재 구독 상태 확인
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.getSubscription();

  if (subscription) {
    // 이미 구독된 상태라면 서버에 등록
    await registerSubscriptionToServer(subscription);
  } else {
    // 구독되지 않은 상태라면 구독 버튼 표시
    showSubscribeButton();
  }
}

async function subscribeUser() {
  // VAPID 키 조회
  const vapidResponse = await fetch('/ajax/get_vapid_key.php');
  const vapidResult = await vapidResponse.json();

  if (!vapidResult.success) {
    alert('푸시 서비스 설정이 완료되지 않았습니다.');
    return;
  }

  // 푸시 구독
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(vapidResult.data.vapid_public_key)
  });

  // 서버에 구독 정보 등록
  await registerSubscriptionToServer(subscription);
}

async function registerSubscriptionToServer(subscription) {
  const response = await fetch('/ajax/subscribe_push.php', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ subscription: subscription.toJSON() })
  });

  const result = await response.json();
  if (result.success) {
    console.log('푸시 알림 구독 완료');
    updateUIForSubscribed();
  } else {
    console.error('구독 등록 실패:', result.message);
  }
}

주의사항

함수 종료: 모든 AJAX 함수는 응답 후 exit()로 종료됩니다
Content-Type: JSON 응답 시 자동으로 application/json 헤더 설정
에러 처리: 클라이언트에서 HTTP 상태코드와 success 필드 모두 확인 필요
보안: 사용자 인증이 필요한 경우 세션 또는 토큰 검증 추가 필요

관련 함수

POST 메서드만 허용됩니다. GET 요청 시 405 에러를 반환합니다.

Content-Type

application/json 형태의 JSON 데이터를 받습니다.

요청 본문

브라우저의 푸시 구독 정보를 담은 JSON 객체입니다.
{
  "subscription": {
    "endpoint": "https://fcm.googleapis.com/fcm/send/...",
    "keys": {
      "p256dh": "BGtFqB7V9OZF...",
      "auth": "rF3dm4Ux..."
    }
  }
}

응답 형식

성공 시 (200 OK)

{
  "success": true,
  "message": "구독이 등록되었습니다."
}

실패 시 (400/500)

{
  "success": false,
  "message": "구독 정보가 올바르지 않습니다."
}

JavaScript 사용 예시

// Service Worker에서 푸시 구독 후 서버에 등록
async function subscribeToPush() {
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: vapidPublicKey
  });

  // 서버에 구독 정보 등록
  const response = await fetch('/ajax/subscribe_push.php', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      subscription: subscription.toJSON()
    })
  });

  const result = await response.json();
  if (result.success) {
    console.log('푸시 구독 등록 성공');
  } else {
    console.error('구독 등록 실패:', result.message);
  }
}

handle_push_unsubscription()

브라우저에서 푸시 구독 해제 요청을 AJAX로 처리합니다.
function handle_push_unsubscription()

요청 형식

{
  "endpoint": "https://fcm.googleapis.com/fcm/send/cJhJBNJGqA..."
}

JavaScript 사용 예시

// 푸시 구독 해제
async function unsubscribeFromPush() {
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.getSubscription();

  if (subscription) {
    // 브라우저에서 구독 해제
    await subscription.unsubscribe();

    // 서버에 해제 알림
    const response = await fetch('/ajax/unsubscribe_push.php', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        endpoint: subscription.endpoint
      })
    });

    const result = await response.json();
    console.log(result.message);
  }
}

get_vapid_public_key()

클라이언트에서 푸시 구독 시 필요한 VAPID 공개키를 AJAX로 조회합니다.
function get_vapid_public_key()

요청 형식

HTTP Method

문서 검색