WordPress AJAX玩法,通过自带的AJAX钩子和通过Rest API两种方法对比

更新于2020年5月2日:本文第一版有一些概念错误,现已修正

基于WordPress项目的开发中,经常会需要用到AJAX请求。相较于原生的前后端实现,WordPress其实提供了两种方法可以更便捷的实现AJAX。

WordPress自带的AJAX钩子实现AJAX

这个方法是现在用的比较多的。原理是前端向“/wp-admin/admin-ajax.php”这个接口发送请求,这个接口会根据请求的action值来处理数据。而根据不同的action值,利用钩子“wp_ajax_nopriv_[action]”和“wp_ajax_[action]”去编写自己的程序处理和返回数据。
如果是要写数据,先在页面生成nonce:

1
$xprofile_nonce = wp_create_nonce ('xprofile_nonce');

前端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var ajax_data = {
	action: "update_xprofile",
	//注意这里有nonce是需要前端生成的
	xprofile_nonce : <?php echo $xprofile_nonce;?>
	xprofile_name :  $("#xprofile_name").val(),
	xprofile_company :  $("#xprofile_company").val()
}
$.post("/wp-admin/admin-ajax.php", ajax_data,
	function(data) {
		//console.log(data);
		if(data=="success"){
			//前端处理成功...
		}else{
			//前端处理其他逻辑...
		}
});

后端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//两个钩子,为安全起见,还是都检验一下nonce吧:
add_action('wp_ajax_nopriv_update_xprofile', 'brain1981_update_xprofile_ajax');
add_action('wp_ajax_update_xprofile', 'brain1981_update_xprofile_ajax');
function brain1981_update_xprofile_ajax(){
	$action = $_POST["action"];
	if ( $action == 'update_xprofile'){
		if ( !wp_verify_nonce($_POST['xprofile_nonce'], 'xprofile_nonce') ) {//如果nonce不对就拒绝执行
			die('Security check!');
		}
		if ( !current_user_can( 'edit_posts' ) ){//如果用户没有对应权限,拒绝处理数据
			die ('You have no permission!');
		}
 
		//处理我们的数据
		//...
		echo "success";//返回成功信号给前端,当然也可以返回任何其他数据
	} 
	die;
}

WordPress Rest API方法实现AJAX

这个方法的原理是创建新的endpoint来处理数据,因此前端数据就要发到自己创建的endpoint去,而不是“admin-ajax.php”接口了。
同样也要生成nonce,由于是要用Rest API,WP规定名称必须为“wp_rest”,WP会自己做认证,无需自己写代码认证。

1
$xprofile_nonce = wp_create_nonce ('wp_rest');

前端,注意“/wp-json/brain1981/v1/xprofile”是我提交数据的endpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var ajax_data = {
	action: "update_xprofile",
	//注意这里有nonce是需要前端生成的
	xprofile_nonce : <?php echo $xprofile_nonce;?>
	xprofile_name :  $("#xprofile_name").val(),
	xprofile_company :  $("#xprofile_company").val()
}
$.ajax({
	url: "/wp-json/brain1981/v1/xprofile",
	type:"POST",
	data: ajax_data,
	dataType: 'json',
	//把nonce放在文件头,WP会自己认证
	beforeSend: function ( xhr ) {
		xhr.setRequestHeader( 'X-WP-Nonce', xprofile_nonce );
	},
	success: function(data){
		console.log(data);
	},
	error:function(XMLHttpRequest ){
		console.log(XMLHttpRequest );
	}
});

后端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
add_action( 'rest_api_init', function () {
	//创建endpoint,实际路径为前两个参数拼合起来
	register_rest_route( 'brain1981/v1', '/xprofile/', array(
		'methods' => 'POST',
		'callback' => 'brain1981_update_xprofile_ajax',
	) );
});
function brain1981_update_xprofile_ajax($request){
	$action = $request['action'];
	if ( $action == 'update_xprofile'){
		//处理我们的数据
		//...
		return "success";//返回成功信号给前端,当然也可以返回任何其他数据,必须用return,不能用print或echo
	} 
	return "fail";
}

两种方法的比较

不同点:nonce的生成和验证方式有较大不同,代码里已有体现;
其实Rest API一般是用来做站外请求的,比如我做微信小程序要和WordPress站点交换数据,就会用到。并且Rest API可以对指定的nonce鉴别用户的id,如果并没有这个id,则赋予当前用户0号id(游客身份)。这样权限之类的事情就很好解决了。
而“admin-ajax.php”接口通常就用在站内AJAX请求,这种场景下即使不通过nonce,用户的id可以直接获取。

概括起来,“admin-ajax.php”接口用在站内,Rest API站内站外都可以用,但是站内“admin-ajax.php”接口感觉更简单一点,也更传统一些。

另外,Rest API的速度会比admin-ajax.php接口获得略微的提升,因为它少加载了一部分WordPress的核心,具体可以参考这篇文章:https://www.npc.ink/11929.html

本站所有文章均为原创,欢迎转载,请注明文章出处:https://blog.brain1981.com/2078.html。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

关注我们的微信公众号-JennyStudio 本站记录了近几年的工作中遇到的一些技术问题和解决过程,“作品集”还收录了本人的大部分作品展示。除了本博客外,我们的工作室网站 – JennyStudio,内有更多作品回顾和展示。
您也可以扫描左边的二维码,关注我们的微信公众号,在微信上查看我们的案例。