چرا پاسخ AJAX شما به JSON تبدیل نمیشود؟ راهنمای تابع wp_send_json
تابع wp_send_json برای ارسال پاسخ JSON در وردپرس؛ بررسی پارامترها، ساختار پاسخ، wp_die، nonce و اشتباهات رایج در AJAX حرفهای.
چرا پاسخ JSON استاندارد حیاتی است؟
در درخواستهای AJAX، سمت سرور باید پاسخ را با ساختار مشخصی ارسال کند تا سمت کلاینت بتواند آن را پردازش کند. اگر پاسخ ساختار استاندارد نداشته باشد، JavaScript نمیتواند آن را پارس کند یا خطا رخ میدهد. تابعwp_send_json() ابزار پایه وردپرس برای این کار است. این تابع هدر Content-Type مناسب را تنظیم میکند، داده را به JSON تبدیل میکند و پردازش را متوقف میسازد. این ساختار پایه توابع تخصصیتر wp_send_json_success و wp_send_json_error است.
تابع wp_send_json چیست؟
تابعwp_send_json() یک تابع هسته وردپرس است که در فایل wp-includes/functions.php تعریف شده است. این تابع یک پاسخ JSON با داده دلخواه ارسال میکند و پردازش PHP را متوقف میسازد.
برخلاف wp_send_json_success و wp_send_json_error، این تابع هیچ کلید استانداردی مانند success اضافه نمیکند. شما میتوانید ساختار دلخواه خود را تعریف کنید.
نکته مهم این است که این تابع در انتهای اجرا wp_die() را فراخوانی میکند و پردازش را متوقف میسازد. بنابراین هر کدی پس از آن اجرا نمیشود.
امضای تابع و پارامترها
امضای این تابع بهشکل زیر است:function wp_send_json( $response, $status_code = null, $options = 0 ) {
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
if ( null !== $status_code ) {
status_header( $status_code );
}
echo wp_json_encode( $response, $options );
if ( wp_doing_ajax() ) {
wp_die( '', '', array( 'response' => null ) );
} else {
die;
}
}
پارامتر اول (response) دادهای است که به JSON تبدیل و ارسال میشود. میتواند آرایه، شیء، رشته یا عدد باشد.
پارامتر دوم (status_code) کد وضعیت HTTP است. اگر null باشد، کد پیشفرض (۲۰۰) استفاده میشود.
پارامتر سوم (options) تنظیمات wp_json_encode است که از وردپرس ۵.۶ اضافه شده است.
سازوکار داخلی تابع
تابعwp_send_json ابتدا هدر Content-Type: application/json را ارسال میکند. سپس اگر کد وضعیت پاس داده شده باشد، آن را تنظیم میکند.
سپس داده را با wp_json_encode به JSON تبدیل میکند و چاپ میکند. در نهایت، پردازش PHP را با wp_die یا die متوقف میکند.
نکته مهم: در محیط AJAX وردپرس، wp_doing_ajax() مقدار true برمیگرداند و پردازش با wp_die متوقف میشود. در سایر محیطها، از die استفاده میشود.
نقش حیاتی wp_die
یکی از پرتکرارترین اشتباهات در استفاده از این تابع، نبود درک نقشwp_die است. پس از فراخوانی wp_send_json، اجرای کد متوقف میشود و هر کدی پس از آن اجرا نمیشود.
اگر بهجای wp_send_json از echo wp_json_encode($data) استفاده کنید، ممکن است کد اضافی پس از آن اجرا شود و پاسخ را خراب کند:
// اشتباه
echo wp_json_encode( array( 'status' => 'ok' ) );
// این کد همچنان اجرا میشود و پاسخ را خراب میکند
error_log( 'Something' );
// صحیح
wp_send_json( array( 'status' => 'ok' ) );
// اجرای کد پس از این خط متوقف میشود
نکته مهم: خروجی پیش از wp_send_json نیز خطای Headers Already Sent ایجاد میکند. همیشه این تابع را در نقطهای فراخوانی کنید که هیچ خروجی پیش از آن چاپ نشده باشد.
ساختار پاسخ JSON
خروجی این تابع دقیقاً همان ساختاری است که شما تعریف میکنید. مثلاً برای یک پاسخ موفق:wp_send_json( array(
'status' => 'ok',
'message' => 'عملیات با موفقیت انجام شد',
'data' => array(
'postId' => 42,
'url' => 'https://example.com/post-42/',
),
) );
خروجی JSON:
{
"status": "ok",
"message": "عملیات با موفقیت انجام شد",
"data": {
"postId": 42,
"url": "https://example.com/post-42/"
}
}
این ساختار انعطافپذیر امکان طراحی پروتکلهای خاص را فراهم میکند. اما برای AJAX استاندارد وردپرس، استفاده از wp_send_json_success و wp_send_json_error توصیه میشود.
کاربردهای عملی در افزونه
ارسال داده با ساختار سفارشی:add_action( 'wp_ajax_myplugin_get_stats', 'myplugin_get_stats_handler' );
function myplugin_get_stats_handler() {
check_ajax_referer( 'myplugin_stats_nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json( array(
'error' => true,
'code' => 'insufficient_permissions',
'message' => 'دسترسی کافی ندارید',
), 403 );
}
$stats = array(
'total_orders' => myplugin_count_orders(),
'total_revenue' => myplugin_sum_revenue(),
'active_customers' => myplugin_count_active_customers(),
);
wp_send_json( array(
'error' => false,
'data' => $stats,
) );
}
نکته مهم: در AJAXهای حساس، بررسی nonce و current_user_can الزامی است. راهنمای این توابع در راهنمای check_ajax_referer و راهنمای current_user_can آمده است.
ارسال داده بهصورت خام:
wp_send_json( array(
'items' => array_map( function( $post ) {
return array(
'id' => $post->ID,
'title' => esc_html( $post->post_title ),
'url' => esc_url( get_permalink( $post ) ),
);
}, $posts ),
) );
نکته مهم: استفاده از esc_html و esc_url در دادههایی که در سمت JavaScript نمایش داده میشوند، از XSS جلوگیری میکند.
تفاوت با wp_send_json_success و error
سه تابع مرتبط وجود دارند که معمولاً با هم اشتباه گرفته میشوند: -wp_send_json: پاسخ خام بدون ساختار استاندارد
- wp_send_json_success: پاسخ با کلید success = true
- wp_send_json_error: پاسخ با کلید success = false
انتخاب بین این سه:
- برای AJAX استاندارد وردپرس، از wp_send_json_success و wp_send_json_error استفاده کنید
- برای پروتکلهای سفارشی، از wp_send_json استفاده کنید
راهنمای این توابع در صفحه wp_send_json_success و صفحه wp_send_json_error آمده است.
نکات امنیتی و اشتباهات رایج
اشتباه اول، نبودwp_die پس از تابع است. اگر بهجای wp_send_json از echo wp_json_encode استفاده کنید، کد اضافی پس از آن اجرا میشود.
اشتباه دوم، نبود nonce است. هر درخواست AJAX باید nonce داشته باشد.
اشتباه سوم، نبود بررسی دسترسی است. برای عملیات حساس، از current_user_can استفاده کنید.
اشتباه چهارم، چاپ خروجی پیش از تابع است. خطای Headers Already Sent رخ میدهد.
اشتباه پنجم، نبود escape در داده است. اگر داده شامل HTML است، باید با wp_kses_post یا esc_html پاکسازی شود.
اشتباه ششم، نبود تست است. باید در سناریوهای مختلف (موفق، خطا، داده خالی) تست کنید.
اشتباه هفتم، ارسال داده حساس به سمت کلاینت است. هر دادهای که به JSON تبدیل میشود، در ابزارهای توسعهدهنده مرورگر قابل مشاهده است.
تحلیل فنی پیشرفته
در نگاه مهندسی، تابعwp_send_json() یک نقطه معماری در لایه AJAX Response است که بر چند جنبه از سیستم اثر میگذارد. لایه اول لایه Serialization است. این تابع داده را با wp_json_encode به JSON تبدیل میکند که خودش از json_encode استفاده میکند و در صورت خطا، مقدار false برمیگرداند.
لایه دوم لایه Header Management است. تنظیم Content-Type صحیح، امکان تفسیر درست پاسخ توسط مرورگر را فراهم میکند.
لایه سوم لایه Execution Termination است. توقف پردازش با wp_die، از ادامه یافتن اجرای کد و خراب شدن پاسخ جلوگیری میکند.
لایه چهارم لایه Status Code است. امکان تنظیم کد وضعیت HTTP، انتقال دقیقتر معنا را فراهم میکند.
لایه پنجم لایه Security است. این تابع خودش escape اضافه ندارد و به عهده توسعهدهنده است.
لایه ششم لایه Integration است. ترکیب wp_send_json با check_ajax_referer و current_user_can یک الگوی کامل امنیتی میسازد.
لایه هفتم لایه Multisite است. در شبکههای Multisite، پاسخ در هر سایت مستقل ارسال میشود.
لایه هشتم لایه Testing است. تستهای End-to-End باید همه سناریوها را پوشش دهند.
مفاهیم پایهای JSON در JSON در ویکیپدیا توضیح داده شده است.
برای مطالعه بیشتر روی توابع مرتبط، میتوانید به راهنمای wp_send_json_success، راهنمای wp_send_json_error، راهنمای هوک wp_ajax، راهنمای هوک wp_ajax_nopriv، راهنمای check_ajax_referer، راهنمای wp_localize_script، راهنمای wp_remote_get و راهنمای wp_remote_post مراجعه کنید.
پرسشهای پرتکرار
تفاوتwp_send_json و wp_send_json_success چیست؟ اولی ساختار دلخواه و دومی ساختار استاندارد با کلید success ارسال میکند.
آیا wp_send_json پردازش PHP را متوقف میکند؟ بله، با wp_die یا die.
آیا میتوان کد وضعیت HTTP پاس داد؟ بله، با پارامتر دوم.
آیا باید nonce بررسی شود؟ بله، در همه درخواستهای AJAX.
آیا این تابع برای REST API مناسب است؟ ممکن است، اما معمولاً WP_REST_Response مناسبتر است.
نتیجه و مسیر ادامه
تابعwp_send_json() ابزار پایه وردپرس برای ارسال پاسخ JSON در AJAX است. استفاده درست از آن یعنی درک نقش حیاتی wp_die، تنظیم کد وضعیت مناسب، بررسی nonce و دسترسی و escape دادهها. اشتباههای کوچک در این تابع اغلب به نبود پاسخ در سمت JavaScript یا خطاهای پردازش منجر میشوند.
اگر این تابع را در پروژهای واقعی به کار بردهاید و رفتار غیرمنتظرهای دیدهاید — بهخصوص در ترکیب با افزونههای کش یا در REST API — تجربهتان میتواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.