You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为WooCommerce Ajax提交的自定义账户编辑表单实现验证

WooCommerce账户编辑表单Ajax提交的验证问题

我正在自定义WooCommerce的form-edit-account.php模板,表单支持用户修改姓名、密码及其他账户信息。原表单提交后会刷新页面,必填字段验证由WooCommerce原生的WC_Form_Handler类管理。

我给表单加上了Ajax提交,实现了无刷新保存数据,数据更新正常,但验证功能失效了。现在有两个思路但不知道怎么推进:

  • 复用WooCommerce原生验证逻辑
  • 用JS或PHP单独实现自定义验证,但不确定这个方案是否合理

希望有人指导如何实现表单字段验证,感谢帮助。


表单示例代码

<form name="Form" class="mts-edit-account" action="<?php echo admin_url('admin-ajax.php'); ?>" method="post" enctype="multipart/form-data" <?php add_action( 'woocommerce_edit_account_form_tag', 'action_woocommerce_edit_account_form_tag' );?> > 
  <!-- Fist & Last Name Field -->
  <div class="row name_surname">
    <div class="form-row">
      <label class="t3" for="account_first_name">Nome *</label>
      <input type="text" placeholder="Inserisci il tuo nome" class="field-settings" name="account_first_name" id="account_first_name" value="<?php echo esc_attr( $user->first_name ); ?>" />
    </div>

    <div class="form-row">
      <label class="t3" for="account_last_name">Cognome *</label>
      <input type="text" placeholder="Inserisci il tuo cognome" class="field-settings" name="account_last_name" id="account_last_name" value="<?php echo esc_attr( $user->last_name ); ?>" />
    </div> 

    <!-- Save Settings -->
    <p style="margin-bottom: 0px!important;">
      <?php wp_nonce_field( 'save_account_details', 'save-account-details-nonce' ); ?>
      <button type="submit" class="edit-account-button" name="save_account_details" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>"><?php esc_html_e( 'Salva modifiche', 'woocommerce' ); ?></button>
      <input type="hidden" name="action" value="save_account_details" />
    </p>
  </div>
</form>

JS文件代码

jQuery(document).ready(function($) {
    
    $('.mts-edit-account').on('submit', function(e) { //form onsubmit event
        e.preventDefault(); // 阻止默认表单提交行为

    //Ajax function
    jQuery.ajax({
      type: "post",
      data: jQuery(".mts-edit-account").serialize(),
      url: "wp-admin/admin-ajax.php",
      success: function(data) {
        alert('Form Inviato');
      }
    });

    });

});

functions.php代码

add_action( 'wp_ajax_save_account_details', 'save_account_details' );
add_action( 'wp_ajax_nopriv_save_account_details', 'save_account_details' );
add_action('woocommerce_save_account_details_errors','save_account_details', 10, 1 );
function save_account_details() {
  // 存储返回给JS的响应数据
  $response = array(
    'error' => false,
  );

  // 尝试返回错误信息的示例(未生效)
  if (trim($_POST['account_first_name']) == '') {
    $response['error'] = true;
    $response['error_message'] = 'Name is required';

  if (trim($_POST['account_first_name']) == '') {
    $response['status'] = false;
    $response['message'] = 'Name is required';
    }else{
    $response['status'] = true;
    $response['message'] = 'success';
    }

    // 出错时终止后续流程,返回响应
    echo json_encode($response);
    exit();
  }

  exit(json_encode($response));
}

解决方案

方案一:复用WooCommerce原生验证逻辑

直接调用WooCommerce内置的验证规则,既能保证逻辑一致性,也不用重复造轮子:

  1. 替换functions.php中的Ajax处理函数:
add_action( 'wp_ajax_save_account_details', 'ajax_save_account_details' );
add_action( 'wp_ajax_nopriv_save_account_details', 'ajax_save_account_details' );

function ajax_save_account_details() {
    // 验证nonce安全令牌
    if ( ! isset( $_POST['save-account-details-nonce'] ) || ! wp_verify_nonce( $_POST['save-account-details-nonce'], 'save_account_details' ) ) {
        wp_send_json_error( array( 'message' => '安全验证失败' ) );
    }

    $current_user = wp_get_current_user();
    $errors = new WP_Error();

    // 触发原生账户保存验证钩子
    do_action( 'woocommerce_save_account_details_errors', $errors, $current_user );

    // 检查验证错误
    if ( $errors->has_errors() ) {
        $error_list = array();
        foreach ( $errors->get_error_messages() as $msg ) {
            $error_list[] = $msg;
        }
        wp_send_json_error( array( 'messages' => $error_list ) );
    }

    // 执行原生账户信息保存逻辑
    WC_Form_Handler::save_account_details( $current_user->ID );

    wp_send_json_success( array( 'message' => '账户信息已保存' ) );
}
  1. 更新JS代码处理错误提示:
jQuery(document).ready(function($) {
    $('.mts-edit-account').on('submit', function(e) {
        e.preventDefault();
        const $form = $(this);
        
        // 清除之前的错误提示
        $form.find('.error-msg').remove();

        $.ajax({
            type: "post",
            data: $form.serialize(),
            url: wp.ajax.settings.url, // 使用WordPress内置的Ajax地址
            dataType: 'json',
            success: function(response) {
                alert(response.data.message);
            },
            error: function(xhr) {
                const res = xhr.responseJSON;
                if (res && res.data.messages) {
                    res.data.messages.forEach(msg => {
                        $form.prepend(`<div class="error-msg" style="color:red; margin-bottom:10px;">${msg}</div>`);
                    });
                }
            }
        });
    });
});

方案二:自定义双重验证(JS前端+PHP后端)

如果需要更灵活的验证规则,可以自己实现前后端双重验证,前端做即时反馈,后端做安全校验:

前端JS验证

jQuery(document).ready(function($) {
    $('.mts-edit-account').on('submit', function(e) {
        const $form = $(this);
        let isFormValid = true;
        $form.find('.field-error').remove();

        // 验证姓名必填
        if (!$.trim($('#account_first_name').val())) {
            isFormValid = false;
            $('#account_first_name').parent().append('<span class="field-error" style="color:red; font-size:12px;">姓名为必填项</span>');
        }
        if (!$.trim($('#account_last_name').val())) {
            isFormValid = false;
            $('#account_last_name').parent().append('<span class="field-error" style="color:red; font-size:12px;">姓氏为必填项</span>');
        }

        // 验证不通过则阻止提交
        if (!isFormValid) {
            e.preventDefault();
            return;
        }

        // 验证通过后提交Ajax
        $.ajax({
            type: "post",
            data: $form.serialize(),
            url: wp.ajax.settings.url,
            dataType: 'json',
            success: function(response) {
                alert(response.data.message);
            },
            error: function(xhr) {
                const res = xhr.responseJSON;
                alert(res.data.message);
            }
        });
    });
});

后端PHP验证

add_action( 'wp_ajax_save_account_details', 'ajax_save_account_details' );
add_action( 'wp_ajax_nopriv_save_account_details', 'ajax_save_account_details' );

function ajax_save_account_details() {
    // 验证nonce
    if ( ! isset( $_POST['save-account-details-nonce'] ) || ! wp_verify_nonce( $_POST['save-account-details-nonce'], 'save_account_details' ) ) {
        wp_send_json_error( array( 'message' => '安全验证失败' ) );
    }

    $error_list = array();

    // 验证姓名
    if (empty(trim($_POST['account_first_name']))) {
        $error_list[] = '姓名为必填项';
    }
    if (empty(trim($_POST['account_last_name']))) {
        $error_list[] = '姓氏为必填项';
    }

    // 密码验证(如果有修改密码字段的话)
    if (!empty($_POST['account_password']) && strlen($_POST['account_password']) < 6) {
        $error_list[] = '密码长度不能少于6位';
    }
    if (!empty($_POST['account_password']) && $_POST['account_password'] !== $_POST['account_password_confirmation']) {
        $error_list[] = '两次输入的密码不一致';
    }

    if (!empty($error_list)) {
        wp_send_json_error( array( 'message' => implode(',', $error_list) ) );
    }

    // 更新用户信息
    $current_user = wp_get_current_user();
    wp_update_user(array(
        'ID' => $current_user->ID,
        'first_name' => sanitize_text_field($_POST['account_first_name']),
        'last_name' => sanitize_text_field($_POST['account_last_name'])
    ));

    // 若修改密码则更新
    if (!empty($_POST['account_password'])) {
        wp_set_password($_POST['account_password'], $current_user->ID);
    }

    wp_send_json_success( array( 'message' => '账户信息已保存' ) );
}

内容的提问来源于stack exchange,提问作者Snorlax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:30:51