Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
•••••
IT NachrichtenDer Universalbote für Admins: Apprise 2.0(29.09.2026 um 13:59 Uhr)
••••
Hacking & PentestingBetrügerische Spendenaufrufe erkennen - Netzpalaver(29.09.2026 um 13:17 Uhr)
••••••
IT NachrichtenDer Universalbote für Admins: Apprise 2.0(29.09.2026 um 13:59 Uhr)
••••
Hacking & PentestingBetrügerische Spendenaufrufe erkennen - Netzpalaver(29.09.2026 um 13:17 Uhr)
•
Intelligence View
⚡ tsecurity.de Intelligence

No More Load On WordPress! Try Ajax Today!

You build a WordPress form. It should save without reloading the page. You click Send. Nothing happens. Or the Network tab shows admin-ajax.php returning a single character: 0. If that sounds familiar, you are not alone. After six years…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

You build a WordPress form. It should save without reloading the page.



You click Send. Nothing happens.



Or the Network tab shows admin-ajax.php returning a single character: 0.



If that sounds familiar, you are not alone. After six years of building WordPress themes, plugins, and WooCommerce projects, I keep seeing the same pattern on client sites. The JavaScript looks fine. The PHP looks fine. But the request never reaches the callback — or it reaches the wrong hook — or the response is not JSON at all.



Most of the time, the problem is not JavaScript skill. It is not understanding how WordPress routes background requests.



This article walks through everything: what AJAX is in WordPress, how admin-ajax.php works, security with nonces, enqueueing scripts, frontend vs admin, JSON responses, debugging, and when to use REST instead. Copy the examples into your own plugin and change the prefixes.









What is AJAX in WordPress?



AJAX lets the browser talk to the server in the background without refreshing the page.



Real examples you have seen:




  • Submit a settings form and show "Saved!" instantly

  • Load more blog posts when someone clicks a button

  • Update a cart count in the header

  • Save a contact form without leaving the page



WordPress does not ask you to invent a custom API endpoint for every plugin. It gives you one built-in router:



/wp-admin/admin-ajax.php



You register an action name in PHP. JavaScript sends that same action in every POST request. WordPress connects the two — similar to add_action(), but triggered from the browser instead of a page load.









The one rule that breaks most projects



Every AJAX request must include:



action=your_action_name



WordPress reads that value and fires a hook:





  • wp_ajax_{action} — logged-in users only


  • wp_ajax_nopriv_{action} — logged-out visitors



If you register wp_ajax_send_form_data in PHP but JavaScript sends send-form-data, nothing runs.



If you only register wp_ajax_ but test while logged out on the public site, nothing runs.



If you forget the action key entirely, WordPress returns 0.



That is normal WordPress behavior. Once you expect it, debugging gets much faster.









The full request loop



Here is what happens on a working setup:




  1. User clicks Submit on a form

  2. JavaScript calls preventDefault() so the page does not reload

  3. JavaScript POSTs to admin-ajax.php with action, nonce, and your fields

  4. WordPress fires wp_ajax_{action} or wp_ajax_nopriv_{action}

  5. Your PHP callback runs, verifies the nonce, sanitizes input

  6. PHP returns JSON via wp_send_json_success() or wp_send_json_error()

  7. JavaScript reads response.success and updates the UI



If any step in that chain is wrong, the feature feels "broken" even when half the code is correct.









Part 1: Your first AJAX handler



Start with the smallest possible example: a logged-in admin request with no nonce yet (we add security in Part 2).



Register the action in PHP:




add_action( 'wp_ajax_send_form_data', 'myplugin_send_form_data_callback' );

function myplugin_send_form_data_callback() {
wp_send_json_success(
array(
'message' => 'Hello from WordPress AJAX!',
)
);
}






What to notice:




  • The action name is send_form_data — prefix it with your plugin name in real projects (myplugin_send_form_data) so you never collide with other plugins

  • JavaScript must send exactly action: 'send_form_data'


  • wp_send_json_success() prints JSON and stops execution — you do not need die() after it



Send the request from JavaScript inside wp-admin:




jQuery.ajax({
method: 'POST',
url: ajaxurl,
data: {
action: 'send_form_data',
},
}).done(function (response) {
console.log(response.data.message);
});






Important detail: the global ajaxurl variable exists automatically in the WordPress admin area. It does not exist on the public frontend. For frontend forms, use wp_localize_script() — covered in Part 3.









Part 2: Secure AJAX with nonces



AJAX endpoints are public URLs. Anyone can send a POST request if they guess your action name.



For any operation that saves, deletes, or changes data, verify a nonce — a short-lived token WordPress generates to prove the request came from your site.






Step 1 — Create the nonce and pass it to JavaScript






wp_localize_script(
'myplugin-admin-js',
'my_ajax_obj',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'myplugin-ajax' ),
)
);






This creates a global JavaScript object my_ajax_obj with two values your script needs: the AJAX URL and the nonce string.



The script handle 'myplugin-admin-js' must match the handle you used in wp_enqueue_script().



The string 'myplugin-ajax' is your nonce action name — use the same string when verifying.






Step 2 — Send the nonce from JavaScript






data: {
action: 'send_form_data',
nonce: my_ajax_obj.nonce,
user_name: 'Hemal',
}









Step 3 — Verify in PHP before doing anything else






function myplugin_send_form_data_callback() {

if ( ! isset( $_POST['nonce'] ) ) {
wp_send_json_error(
array(
'message' => 'Nonce is missing.',
)
);
}

$nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ) );

if ( ! wp_verify_nonce( $nonce, 'myplugin-ajax' ) ) {
wp_send_json_error(
array(
'message' => 'Security check failed.',
)
);
}

$name = sanitize_text_field( wp_unslash( $_POST['user_name'] ?? '' ) );

wp_send_json_success(
array(
'message' => 'Success!',
'name' => $name,
)
);
}






Without a nonce, anyone on the internet can spam your endpoint. With a nonce, only requests that include a valid token from your enqueued script will pass verification.









Part 3: Enqueue scripts and pass data correctly



If your form lives on a custom admin page, you must load your JavaScript on that screen and pass the AJAX URL yourself.




add_action( 'admin_enqueue_scripts', 'myplugin_load_admin_scripts' );

function myplugin_load_admin_scripts() {

wp_enqueue_script(
'myplugin-admin-js',
plugin_dir_url( __FILE__ ) . 'assets/js/admin.js',
array( 'jquery' ),
'1.0.0',
true
);

wp_localize_script(
'myplugin-admin-js',
'my_ajax_obj',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'myplugin-ajax' ),
)
);
}






What each part does:




































Part Purpose
admin_enqueue_scripts Loads assets only in wp-admin
'myplugin-admin-js' Script handle — must match in wp_localize_script
array( 'jquery' ) Loads jQuery before your script

true at the end
Loads script in footer (after DOM exists)
wp_localize_script Exposes my_ajax_obj.ajax_url and my_ajax_obj.nonce to JS
admin_url( 'admin-ajax.php' ) Full URL — works on local, staging, and subfolder installs


Never hard-code /wp-admin/admin-ajax.php. Always use admin_url().









Part 4: Put the pieces together



A clean plugin splits responsibilities:





  • Assets class — enqueue JS, pass nonce and URL


  • Admin page — render the HTML form


  • Ajax class — register wp_ajax_* hooks and callbacks



On the JavaScript side:




(function ($) {
$(document).ready(function () {

$('.myplugin-ajax-form').on('submit', function (event) {
event.preventDefault();

var $form = $(this);

$.ajax({
method: 'POST',
url: my_ajax_obj.ajax_url,
data: {
action: 'send_form_data',
nonce: my_ajax_obj.nonce,
user_name: $form.find('[name="user_name"]').val(),
},
}).done(function (response) {
if (response.success) {
alert(response.data.message);
} else {
alert(response.data.message || 'Request failed.');
}
});

});

});
})(jQuery);






When the user clicks Send:




  1. Normal form submit is blocked

  2. POST goes to admin-ajax.php

  3. WordPress reads action=send_form_data

  4. Hook wp_ajax_send_form_data fires

  5. PHP verifies nonce and returns JSON

  6. JavaScript shows the result



That is the entire system. Nothing hidden.









Part 5: JSON responses — success and error



Use WordPress helpers. Do not echo random text and call die() — it breaks JSON parsing in JavaScript.



Success:




wp_send_json_success(
array(
'message' => 'Saved!',
'id' => 123,
)
);






Error:




wp_send_json_error(
array(
'message' => 'Something went wrong.',
),
400
);






JavaScript receives:




{
"success": true,
"data": {
"message": "Saved!",
"id": 123
}
}






Always check response.success before reading response.data.



Always sanitize before save:




$name  = sanitize_text_field( wp_unslash( $_POST['user_name'] ?? '' ) );
$email = sanitize_email( wp_unslash( $_POST['email'] ?? '' ) );
$id = absint( $_POST['item_id'] ?? 0 );












Part 6: Frontend AJAX for logged-out users



Public contact forms need the nopriv hook.



Register both with the same callback:




add_action( 'wp_ajax_send_form_data', 'myplugin_send_form_data_callback' );
add_action( 'wp_ajax_nopriv_send_form_data', 'myplugin_send_form_data_callback' );























Hook When it runs
wp_ajax_{action} User is logged in
wp_ajax_nopriv_{action} User is not logged in


This is the most common "works for me, broken for clients" bug. You test as admin. Real visitors are logged out.



For admin-only actions (delete post, save settings), skip nopriv and add current_user_can() inside the callback instead.









Part 7: Enqueue on the frontend



Admin uses admin_enqueue_scripts. The public site uses wp_enqueue_scripts:




add_action( 'wp_enqueue_scripts', 'myplugin_load_public_scripts' );

function myplugin_load_public_scripts() {

wp_enqueue_script(
'myplugin-public-js',
plugin_dir_url( __FILE__ ) . 'assets/js/public.js',
array( 'jquery' ),
'1.0.0',
true
);

wp_localize_script(
'myplugin-public-js',
'my_ajax_obj',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'myplugin-ajax' ),
)
);
}






Same pattern. Different hook. If the script is not enqueued on the page where your form appears, the JavaScript never runs — even if PHP is perfect.









Part 8: Using fetch() instead of jQuery



WordPress does not care which library you use. It cares about POST, action, and nonce.




document.querySelector('.myplugin-ajax-form')?.addEventListener('submit', async function (event) {

event.preventDefault();

var form = event.target;
var formData = new FormData();

formData.append('action', 'send_form_data');
formData.append('nonce', my_ajax_obj.nonce);
formData.append('user_name', form.querySelector('[name="user_name"]').value);

var response = await fetch(my_ajax_obj.ajax_url, {
method: 'POST',
body: formData,
credentials: 'same-origin',
});

var json = await response.json();

if (json.success) {
alert(json.data.message);
} else {
alert(json.data.message || 'Request failed.');
}

});












Part 9: admin-ajax.php vs REST API



WordPress offers two async patterns:



admin-ajax.php




  • URL: /wp-admin/admin-ajax.php

  • Register with add_action( 'wp_ajax_*' )

  • Best for classic plugins, wp-admin UI, small forms



REST API




  • URL: /wp-json/your-namespace/v1/your-route

  • Register with register_rest_route()

  • Best for headless sites, Gutenberg blocks, mobile apps



For most theme and plugin work inside WordPress admin, admin-ajax.php is still the fastest path. Move to REST when you need standard HTTP routes, external consumers, or block editor integration.









Part 10: Debugging when AJAX fails



Check these in order before guessing:





  1. Action name — identical string in PHP hook and JavaScript action field?


  2. Network tab — open DevTools, find admin-ajax.php, read the response body


  3. Logged out? — did you register wp_ajax_nopriv_?


  4. Script loaded? — is wp_enqueue_script running on this exact page?


  5. Nonce — created, passed to JS, sent back, verified with same action string?



Common responses:




























Response Meaning
0 Action not registered or callback not found
-1 Nonce failed or permission denied
JSON with "success": false
Callback ran but returned an error
Empty or HTML PHP error, or you used echo instead of JSON helpers


Temporary logging in PHP:




error_log( print_r( $_POST, true ) );






Enable WP_DEBUG_LOG in wp-config.php and read wp-content/debug.log.









Quick reference








































I want to… Use
Handle logged-in AJAX add_action( 'wp_ajax_{action}', 'callback' )
Handle logged-out AJAX add_action( 'wp_ajax_nopriv_{action}', 'callback' )
Pass URL + nonce to JS wp_localize_script()
Return success JSON wp_send_json_success( $data )
Return error JSON wp_send_json_error( $data )
Verify token wp_verify_nonce( $nonce, 'action-name' )
AJAX router URL admin_url( 'admin-ajax.php' )








Common mistakes




  1. Missing action in JavaScript — WordPress returns 0

  2. Mismatched action names between PHP and JS

  3. Forgetting wp_ajax_nopriv_ on public forms

  4. No nonce on write operations

  5. Using echo instead of wp_send_json_*

  6. Hard-coding /wp-admin/admin-ajax.php

  7. Not sanitizing $_POST

  8. Scheduling script on wrong hook or wrong admin page









Checklist before shipping




  • Action name is unique and prefixed (myplugin_send_form_data)


  • wp_ajax_ registered (and wp_ajax_nopriv_ if public)

  • Nonce created, passed to JS, verified in PHP

  • Input sanitized, output escaped


  • wp_send_json_success / wp_send_json_error used

  • Script enqueued on the correct hook and page

  • Tested logged in and logged out

  • Network tab checked for 0, -1, or 500 errors









What you can build with this



Once the loop is clear, many features become straightforward:




  • Live search and filters

  • Infinite scroll / load more

  • Theme option panels that save instantly

  • Newsletter and contact forms

  • Admin dashboards that refresh without reload

  • WooCommerce-style cart updates



Same WordPress hook thinking — triggered from JavaScript.









Read more



Medium — full walkthrough with additional examples:


https://medium.com/@hemal.akanda.39/no-refresh-in-wordpress-by-ajax-4942c5e80bd2



Substack — same topic in plain English, no code:


https://substack.com/@mdhemalakhand/note/p-201821073









What I am building now



After years of WordPress client work, I am building AppsLaunch — branded Android and iPhone apps for local service businesses from one dashboard.



How it works:




  • Create your company and add logo, colors, services, and products

  • Customers browse in the app and send inquiries — leads land in your dashboard inbox

  • Build signed Android and iPhone apps from the cloud and publish to Google Play and the App Store

  • Each business gets its own app name and store listing — not a generic builder brand



Plans from $30/month. No per-lead fees on paid plans.



https://applaunch.teamzlab.com/









Final thought



WordPress AJAX is four ideas on every project:




  1. Register the action in PHP

  2. Send the same action name from JavaScript

  3. Secure the request with nonces and sanitization

  4. Return clean JSON



Once you see that loop, no-refresh forms stop feeling like magic and start feeling like normal WordPress development.

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph3 Knoten / 2 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten No More Load On WordPress! Try Ajax Today!

Thematisch verwandte Begriffe: More, Load, WordPress, Ajax · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-102247 | A vulnerability was detected in FastAdmin 1.6.1.20250430/1.6.5.20260602…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag