WordPress AJAX:AJAX 钩子和 Rest API 对比

编辑于:2021年12月21日
WordPress AJAX:AJAX 钩子和 Rest API 对比

WordPress 自带的 AJAX 钩子(admin-ajax.php)实现 AJAX 和 WordPress Rest API 方法实现 AJAX 是在 WordPress 项目的开发中,相较于原生的前后端实现,更便捷的实现 AJAX 的两种方法。

WordPress 自带的 AJAX 钩子实现 AJAX

这个方法是现在用的比较多的。原理是前端向/wp-admin/admin-ajax.php这个接口发送请求,这个接口会根据请求的action值来处理数据。

而根据不同的 action 值,利用钩子 wp_ajax_nopriv_[action]wp_ajax_[action] 去编写自己的程序处理和返回数据。

如果是要写数据,先在页面生成 nonce:

$xprofile_nonce = wp_create_nonce ('xprofile_nonce');

前端

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{
			//前端处理其他逻辑...
		}
});

后端

//两个钩子,为安全起见,还是都检验一下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 会自己做认证,无需自己写代码认证。

$xprofile_nonce = wp_create_nonce ('wp_rest');

前端

注意 /wp-json/brain1981/v1/xprofile 是我提交数据的 endpoint

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 );
	}
});

后端

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://wangejiba.com/4900.html

相关推荐