Okay, so I programmed the following ajax code for my plugin, and I'm wondering why it's not working:
JavaScript:
function myFunction() {
let dataContent = "hello";
let myData = {
// Nonce
_ajax_nonce: "<?php wp_create_nonce( 'nonce-name' );?>",
// Action Hook name for Ajax Call
action: 'my_action',
// Currently typed username
data: dataContent
};
// To send the JavaScript object to the server, convert it into a JSON string
let myDataJSON = JSON.stringify(myData);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
};
let link = "<?php admin_url( 'admin-ajax.php' );?>";
xhttp.open("POST", link, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("data=" + myDataJSON);
}
PHP (Callback):
function answer() {
check_ajax_referer( 'nonce-name' );
echo "hello";
}
PHP (Hook):
add_action( 'wp_ajax_my_action', 'answer' );
When launching the call, I get "undefined" displayed in the alert window. What's wrong?
Okay, so I programmed the following ajax code for my plugin, and I'm wondering why it's not working:
JavaScript:
function myFunction() {
let dataContent = "hello";
let myData = {
// Nonce
_ajax_nonce: "<?php wp_create_nonce( 'nonce-name' );?>",
// Action Hook name for Ajax Call
action: 'my_action',
// Currently typed username
data: dataContent
};
// To send the JavaScript object to the server, convert it into a JSON string
let myDataJSON = JSON.stringify(myData);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
};
let link = "<?php admin_url( 'admin-ajax.php' );?>";
xhttp.open("POST", link, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("data=" + myDataJSON);
}
PHP (Callback):
function answer() {
check_ajax_referer( 'nonce-name' );
echo "hello";
}
PHP (Hook):
add_action( 'wp_ajax_my_action', 'answer' );
When launching the call, I get "undefined" displayed in the alert window. What's wrong?
Share Improve this question edited Apr 14, 2020 at 19:28 fuxia♦ 107k39 gold badges255 silver badges459 bronze badges asked Apr 14, 2020 at 16:57 JoeJoe 351 silver badge9 bronze badges2 Answers
Reset to default 1There are 4 filters to work with WordPress ajax. According to your description, the following conditions are assumed
wp_ajax_{$action}
is for running in frontend and the user is logged in- if echo something in the php file, it will not reflect in the frontend. Javascript alert will output 'hello'
- your javascript seems to be done in PHP and generate javascript, I suppose you have added proper header
According to WP Codex, the 4 filters for ajax are
wp_ajax_{$action}
Fires authenticated Ajax actions for logged-in users.wp_ajax_nopriv_{$action}
Fires non-authenticated Ajax actions for logged-out users.admin_post_{$action}
Fires on an authenticated admin post request for the given action.admin_post_nopriv_{$action}
Fires on a non-authenticated admin post request for the given action.
Some facts about the code
- There are missing
echo
to output nonce and admin_url - the script is actually not working (it is according to your shared code, there might be additional code. Anyway, if going to browser inspector, it gives 400 bad request error. It did not send ajax successfully.
There are a few issues in the code, here is the fixed script with missing pieces that I need for doing the test. I put the code into my theme functions.php
and javascript code into test.php
In the testing, have put in the theme functions.php
// load the javascript
function q364077_enqueue_scripts()
{
wp_enqueue_script('test-custom-scripts', get_theme_file_uri('/test.php'), array(), 't' . time(), true);
}
add_action('wp_enqueue_scripts', 'q364077_enqueue_scripts', 101);
// The ajax answer()
add_action( 'wp_ajax_my_action', 'answer' );
function answer() {
// check_ajax_referer( 'nonce-name' );
echo "hello";
wp_die(); // terminate script after any required work, if not, the response text will output 'hello0' because the of function return after finish
}
The test.php is put in the theme folder, same level as functions.php
<?php
// inside the javascript test.php
/** Load WordPress Bootstrap */
// for test.php in theme folders
require_once( ( ( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) ) . '/wp-load.php' ); // to use admin_url(), if not, the script will be broken
// for output the javascript through php
header("Content-type: text/javascript");?>
function myFunction() {
let dataContent = "hello";
let myData = {
_ajax_nonce: "<?php echo wp_create_nonce( 'nonce-name' );?>", // haven't added echo here, it is actually blank in output.
// Action Hook name for Ajax Call
action: 'my_action',
// Currently typed username
data: dataContent
};
// To send the JavaScript object to the server, convert it into a JSON string
let myDataJSON = JSON.stringify(myData);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
};
let link = "<?php echo admin_url( 'admin-ajax.php' );?>"; // require "echo" to output, otherwise, it will alert unexpected output
xhttp.open("POST", link, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
// It is explained in the following, I use static value for illustration purpose
xhttp.send('_ajax_nonce=efc5e4029d&action=my_action&data=hello');
The data need to be serialized, not only string. Your data look likes
{"_ajax_nonce":"efc5e4029d","action":"my_action","data":"hello"}
Ajax looks for this which jQuery has done for user. For Vanilla JS, it need to be done manually or using any existing vanilla js tools.
_ajax_nonce=efc5e4029d&action=my_action&data=hello
You may test the above code by fixing the 'echo' and putting a static value of the data to experience and may also go to the inspector, Chrome as an example.
in the inspector -> Network Tab -> when you fire myFunction() in console log, it return the status to you with request/response header, in that way, it helps bug fixing.
The above code tested and proved working in a fresh WordPress 5.3.2, default twenty twenty theme.
You're focusing on the script - side, but the addition of slashes to the json object only happens once the data is sent and received by the server, before being sent back to javascript. Guess I need to find out how to define the datatype in pure javascript in wordpress, with jquery its simply by using dataType:json (tried to serialize in pure js, didn't work, lmk if u get the answer, and thx!)