自定义Ajax表单更新Woocommerce订单时的当前用户验证问题
问题根源分析
- 后端响应不完整:PHP函数中,当用户未登录时未返回任何JSON响应,导致AJAX请求收到空内容,前端误判为操作成功。
- AJAX错误判断逻辑偏差:
wp_send_json_error()默认返回HTTP 200状态码,而前端AJAX的error回调仅在HTTP状态码非200时触发,因此即使后端返回错误信息,前端仍会进入success回调。
修复步骤
1. 完善后端PHP函数
确保所有分支都返回明确的JSON响应,并在验证失败时返回对应HTTP状态码:
add_action( 'wp_ajax_update_custom_field_order_expense_php', 'update_custom_field_order_expense_php' ); add_action('wp_ajax_nopriv_update_custom_field_order_expense_php', 'update_custom_field_order_expense_php'); function update_custom_field_order_expense_php() { // 校验必要参数是否存在 if ( !isset($_POST['orderid'], $_POST['expense'], $_POST['expense_reason']) ) { wp_send_json_error( array('message' => '缺少必要参数'), 400 ); exit; } // 过滤用户输入,提升安全性 $order_id = sanitize_text_field($_POST['orderid']); $order_expense = sanitize_text_field($_POST['expense']); $order_expense_reason = sanitize_textarea_field($_POST['expense_reason']); // 检查订单是否存在 $order = wc_get_order( $order_id ); if ( !$order ) { wp_send_json_error( array('message' => '订单不存在'), 404 ); exit; } // 校验用户登录状态 if ( !is_user_logged_in()) { wp_send_json_error( array('message' => '请先登录'), 401 ); exit; } $current_user = wp_get_current_user(); $current_user_id = $current_user->ID; $driver_id = get_post_meta($order_id, 'lddfw_driverid', true); // 校验用户是否有权限修改该订单 if( empty($driver_id) || $current_user_id != $driver_id ){ wp_send_json_error( array('message' => '无权限修改此订单'), 403 ); exit; } // 更新订单元数据 $order->update_meta_data( 'Driver Expense', $order_expense ); $order->update_meta_data( 'Driver Expense Reason', $order_expense_reason); $order->save(); wp_send_json_success( array('message' => '费用提交成功') ); exit; }
- 新增参数校验、订单存在性校验,拦截无效请求
- 每个失败分支返回对应HTTP状态码,明确错误类型
- 使用
sanitize_*系列函数过滤用户输入,避免XSS等安全问题
2. 修改前端AJAX逻辑
调整回调函数,同时依据HTTP状态和响应内容判断操作结果:
jQuery(document).ready(function($) { $('#expense_form').on('submit', function(e) { e.preventDefault(); var orderid = $('#exp_order_no').val(); var expense = $('#expense_amt').val(); var expense_reason = $('#expense_reason').val(); $.ajax({ url: '<?php echo admin_url('admin-ajax.php'); ?>', type: 'POST', data: { action:'update_custom_field_order_expense_php', orderid: orderid, expense: expense, expense_reason:expense_reason }, success: function( response ) { // 即使HTTP状态为200,也要检查后端返回的success标识 if (response.success) { console.log( response.data.message ); alert(response.data.message); location.reload(); } else { console.log( response.data.message ); alert(response.data.message); } }, error: function( xhr ) { // 解析HTTP错误对应的提示信息 var errorMsg = '提交失败,请稍后重试'; if (xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) { errorMsg = xhr.responseJSON.data.message; } console.log( errorMsg ); alert(errorMsg); } }); }); });
- 在
success回调中检查response.success字段,区分后端返回的成功/错误状态 - 在
error回调中解析响应体的错误信息,给用户更精准的提示 - 统一使用后端返回的提示文本,避免前后端提示不一致
额外优化建议
- 前端输入增强:除HTML5的
pattern校验外,可在JS中添加费用非零、非负等逻辑校验 - 防重复提交:提交表单时添加加载状态,禁用提交按钮,避免用户重复操作
- 订单ID优化:若用户为司机,可自动加载其关联的订单列表,减少手动输入错误
内容的提问来源于stack exchange,提问作者Rishikesh Dubey
相关产品推荐
相关产品推荐

