我有一个WordPress网站,我正在配置使用jQuery / AJAX查询和加载div框内的帖子。
以下是functions.php
中的内容(大体简化,自然而然):
function mysite_enqueue_scripts() {
wp_register_script( 'mysite_front' , get_bloginfo( 'template_url' ) . '/js/front.js' , array( 'jquery' ) );
wp_enqueue_script( 'mysite_front' ); //loads the front-side jquery
wp_localize_script( 'mysite_front' , 'AJAX' , array(
'ajaxurl' => admin_url( 'admin-ajax.php' ) ,
'nonce' => wp_create_nonce( 'mysite-ajax-nonce' )
) ); //localizes the script
}
add_action( 'wp_enqueue_scripts' , 'mysite_enqueue_scripts' , 100 );
add_action( 'wp_ajax_nopriv_load_items' , 'mysite_ajax_load_items' );
add_action( 'wp_ajax_load_items' , 'mysite_ajax_load_items' );
function mysite_ajax_load_items() {
if( !check_ajax_referer( 'mysite-ajax-nonce' , 'nonce' , false ) ) {
wp_send_json( array( 'error' => 'nonce error' ) );
return;
} else {
[[[all the WP query stuff goes here and creates an $html string]]]
wp_send_json( array( 'html' => $html ) );
}
}
jQuery front.js
:
jQuery( document ).ready( function($) {
$( '#mysite-load' ).click( function() {
var postData = {
action : 'load_items' ,
nonce : AJAX.nonce
};
jQuery.post(
AJAX.ajaxurl , postData , function( response ) {
if( typeof( response['html'] ) !== 'undefined' ) {
$( '#mysite-load' ).html( response['html'] );
} else if( typeof( response['error'] ) !== 'undefined' ) {
$( '#mysite-load' ).html( 'Error: ' + response['error'] );
}
}
);
});
});
HTML:
<div id="mysite-load">click</div>
当我没有登录网站的wp-admin并加载此页面时,一切都运行良好。
但是当我登录网站的wp-admin并加载此页面时,它会返回'nonce error'
错误,而不是应该加载的HTML。
问题不是浏览器特定的;尝试在Safari和Chrome中收到同样的错误。我还尝试使用wp_verify_nonce()
代替check_ajax_referer()
,并收到相同的结果。
知道为什么会这样吗?
答案 0 :(得分:0)
我确实遇到了这个问题。我发现问题是nonces是以特定的方式处理API AJAX请求。在我的例子中,这是使用自定义端点,但我想它对任何API调用都是一样的。
相关文档在此处:https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/。感兴趣的特定段落在Cookie身份验证下:
对于制作手动Ajax请求的开发人员,需要使用nonce 随每个请求传递。 API使用动作设置为的nonce wp_rest。然后可以通过_wpnonce数据将这些传递给API 参数(POST数据或GET请求的查询)或通过 X-WP-Nonce标题。
在实践中,我发现这意味着您必须至少使用动作设置为“wp-rest”的随机数,以确保登录用户在API中正确加载请求上下文。否则,您将使用登录用户生成自定义nonce,但尝试使用匿名用户进行验证(除非您使用此nonce,否则这是API调用的默认值)。
$nonce = wp_create_nonce( 'wp_rest' );
然后,您还需要确保通过X-WP-Nonce标头返回通过此操作生成的随机数。
$.ajax({
type: 'POST',
url: your-api-url-here,
contentType: 'application/json; charset=UTF-8',
beforeSend: function(jqXhr) {
jqXhr.setRequestHeader('X-WP-Nonce', nonce)
},
data: your-data-here
})
(为了清楚起见,我省略了用于将随机数转移到javascript上下文中的脚本本地化部分,但是你在问题中有那些,所以我假设一切都很好)
完成此操作后,您的AJAX调用将不再是匿名的(如果您已登录),并且您的其他随机数现在将正确验证。