为什么我的 ajax 功能没有按预期工作?
why is my ajax function not working as expected?
所以我的 class 看起来像这样:
class Myclass{
private $nonce;
public function __construct(){
if( get_current_screen()->id == 'nav-menus' ){
$this->nonce = 'my-plugin-nonce';
}
add_action( 'wp_ajax_run_action', array( $this, 'run' ) );
wp_localize_script(
'my-script',
'my_script',
array( 'nonce' => wp_create_nonce( $this->nonce ),
'ajaxurl' => admin_url('admin-ajax.php'),
)
);
}
public function run(){
if( ! wp_verify_nonce( $_POST['nonce'], $this->nonce ) )
return false;
wp_send_json_success();
}
}
new Myclass;
这里是 javascript 代码:
$.ajax({
type: 'POST',
dataType: 'json',
url: my_script.ajaxurl,
data: {
'action': 'run_action',
'nonce' : my_script.nonce,
},
complete: function( object ) {
console.log( object.responseJSON )
}
});
问题是,当我尝试从我的 javascript ajax 函数中调用 run_action
操作时,它没有 return 正确。
请注意,我已正确本地化我的脚本,对象中包含的所有数据都已正确呈现。
为什么会这样?
抄本注释:
wp_localize_script() MUST be called after the script has been registered using wp_register_script()
or wp_enqueue_script()
.
所以你的工作流程应该如下:
- 注册脚本
- 本地化
- 排队您的本地化脚本。
- 将其与适当的操作联系起来:
wp_enqueue_scripts
或 admin_enqueue_scripts
例如:
向您的 __construct
方法添加操作:
add_action('wp_enqueue_scripts', array($this, 'registerAjaxScript'));
然后创建一个方法来注册和本地化您的脚本:
function registerAjaxScript() {
wp_register_script('my-script',
string $src,
array $deps,
string or bool $ver,
bool $in_footer
);
wp_localize_script('my-script',
'my_script',
array( 'nonce' => wp_create_nonce( $this->nonce ),
'ajaxurl' => admin_url('admin-ajax.php'),
)
);
}
脚本的本地化必须在您包含脚本的页面上完成(即在这种情况下在 nav-menus.php 管理页面上)- 您不包含实际排队的代码javascript,但你所做的代码 post 向我暗示你实际上是在尝试在 ajax 调用本身中本地化脚本 - 这是行不通的。
我在下面重新整理了您的代码并添加了注释来解释每项更改:
class Myclass {
/**
* No reason not to assign this already (and I've renamed it to explicitly,
* let people reading the code know that it is not the nonce itself, but the
* name of the nonce action - fooled me for a minute or two :p
*/
private $nonce_action_name = 'my-plugin-nonce';
/**
* The __construct function is great for hooking everything you need to
* hook, and for setting initial variables. Pretty much anything else
* should NOT be in this function though!
*/
public function __construct(){
// Register your ajax action.
add_action( 'wp_ajax_run_action', array( $this, 'run' ) );
// Hook into the appropriate action for admin scripts
add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
}
public function scripts() {
/**
* I've negated your if-statement here - basically we don't want to do
* anything at all if we are not on the correct page - which is clearer
* this way - also you had it in the __construct function, which will
* actually produce a fatal error, since get_current_screen is not
* usually defined yet at that point(!)
*/
if( get_current_screen()->id !== 'nav-menus' ){
return;
}
//Now enqueue (or register) the script
wp_enqueue_script('my-script', plugins_url('/my-script.js', __FILE__));
//Then localize it
wp_localize_script(
'my-script',
'my_script',
array(
'nonce' => wp_create_nonce( $this->nonce_action_name ),
'ajaxurl' => admin_url('admin-ajax.php'),
)
);
}
/**
* Actual ajax handler
*/
public function run(){
if( ! wp_verify_nonce( $_POST['nonce'], $this->nonce_action_name ) ) {
//This is a guess, but I think you'll want to wp_send_json_error
//here to match up with your success below
wp_send_json_error();
} else {
wp_send_json_success();
}
/**
* Always recommended to explicitly die() after handling ajax - though
* the wp_send_json_* family probably does it for you.
*/
die();
}
}
new Myclass;
最后要注意的是 ajaxurl
实际上总是在管理员中定义,因此您实际上不需要将其添加到您的本地化中(尽管添加一些额外的字节只会造成伤害)。
所以我的 class 看起来像这样:
class Myclass{
private $nonce;
public function __construct(){
if( get_current_screen()->id == 'nav-menus' ){
$this->nonce = 'my-plugin-nonce';
}
add_action( 'wp_ajax_run_action', array( $this, 'run' ) );
wp_localize_script(
'my-script',
'my_script',
array( 'nonce' => wp_create_nonce( $this->nonce ),
'ajaxurl' => admin_url('admin-ajax.php'),
)
);
}
public function run(){
if( ! wp_verify_nonce( $_POST['nonce'], $this->nonce ) )
return false;
wp_send_json_success();
}
}
new Myclass;
这里是 javascript 代码:
$.ajax({
type: 'POST',
dataType: 'json',
url: my_script.ajaxurl,
data: {
'action': 'run_action',
'nonce' : my_script.nonce,
},
complete: function( object ) {
console.log( object.responseJSON )
}
});
问题是,当我尝试从我的 javascript ajax 函数中调用 run_action
操作时,它没有 return 正确。
请注意,我已正确本地化我的脚本,对象中包含的所有数据都已正确呈现。
为什么会这样?
抄本注释:
wp_localize_script() MUST be called after the script has been registered using
wp_register_script()
orwp_enqueue_script()
.
所以你的工作流程应该如下:
- 注册脚本
- 本地化
- 排队您的本地化脚本。
- 将其与适当的操作联系起来:
wp_enqueue_scripts
或admin_enqueue_scripts
例如:
向您的 __construct
方法添加操作:
add_action('wp_enqueue_scripts', array($this, 'registerAjaxScript'));
然后创建一个方法来注册和本地化您的脚本:
function registerAjaxScript() {
wp_register_script('my-script',
string $src,
array $deps,
string or bool $ver,
bool $in_footer
);
wp_localize_script('my-script',
'my_script',
array( 'nonce' => wp_create_nonce( $this->nonce ),
'ajaxurl' => admin_url('admin-ajax.php'),
)
);
}
脚本的本地化必须在您包含脚本的页面上完成(即在这种情况下在 nav-menus.php 管理页面上)- 您不包含实际排队的代码javascript,但你所做的代码 post 向我暗示你实际上是在尝试在 ajax 调用本身中本地化脚本 - 这是行不通的。
我在下面重新整理了您的代码并添加了注释来解释每项更改:
class Myclass {
/**
* No reason not to assign this already (and I've renamed it to explicitly,
* let people reading the code know that it is not the nonce itself, but the
* name of the nonce action - fooled me for a minute or two :p
*/
private $nonce_action_name = 'my-plugin-nonce';
/**
* The __construct function is great for hooking everything you need to
* hook, and for setting initial variables. Pretty much anything else
* should NOT be in this function though!
*/
public function __construct(){
// Register your ajax action.
add_action( 'wp_ajax_run_action', array( $this, 'run' ) );
// Hook into the appropriate action for admin scripts
add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
}
public function scripts() {
/**
* I've negated your if-statement here - basically we don't want to do
* anything at all if we are not on the correct page - which is clearer
* this way - also you had it in the __construct function, which will
* actually produce a fatal error, since get_current_screen is not
* usually defined yet at that point(!)
*/
if( get_current_screen()->id !== 'nav-menus' ){
return;
}
//Now enqueue (or register) the script
wp_enqueue_script('my-script', plugins_url('/my-script.js', __FILE__));
//Then localize it
wp_localize_script(
'my-script',
'my_script',
array(
'nonce' => wp_create_nonce( $this->nonce_action_name ),
'ajaxurl' => admin_url('admin-ajax.php'),
)
);
}
/**
* Actual ajax handler
*/
public function run(){
if( ! wp_verify_nonce( $_POST['nonce'], $this->nonce_action_name ) ) {
//This is a guess, but I think you'll want to wp_send_json_error
//here to match up with your success below
wp_send_json_error();
} else {
wp_send_json_success();
}
/**
* Always recommended to explicitly die() after handling ajax - though
* the wp_send_json_* family probably does it for you.
*/
die();
}
}
new Myclass;
最后要注意的是 ajaxurl
实际上总是在管理员中定义,因此您实际上不需要将其添加到您的本地化中(尽管添加一些额外的字节只会造成伤害)。