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

如何处理AJAX提交wp_mail表单的验证错误与成功提示问题

问题描述

我有一个通过AJAX和wp_mail()提交的表单,通过短码嵌入页面。目前存在的问题是:即使消息未发送(比如验证出错),页面仍会显示发送成功的提示。我尝试绑定response,但控制台返回的响应包含验证错误信息,请问如何处理响应,使得验证出错时不显示提交成功的提示?

相关代码

PHP代码

add_shortcode('contact-form', 'display_contact_form');

function display_contact_form()
{
    $validation_messages = [];

    if (isset($_POST['contact_form'])) {
        //Sanitize the data
        $full_name = isset($_POST['full_name']) ? sanitize_text_field($_POST['full_name']) : '';
        $email     = isset($_POST['email']) ? sanitize_text_field($_POST['email']) : '';
        $message   = isset($_POST['message']) ? sanitize_textarea_field($_POST['message']) : '';

        //Validate the data
        if (strlen($full_name) === 0) {
            $validation_messages[] = esc_html__('Please enter a valid name.');
        }

        if (strlen($email) === 0 || !is_email($email)) {
            $validation_messages[] = esc_html__('Please enter a valid email address.');
        }

        if (strlen($message) === 0) {
            $validation_messages[] = esc_html__('Please enter a valid message.');
        }

        //Send an email to the WordPress administrator if there are no validation errors
        if (empty($validation_messages)) {
            $mail    = get_option('admin_email');
            $subject = 'New message from ' . $full_name;
            $message_content = $message . ' - The email address of the customer is: ' . $mail;

            wp_mail($mail, $subject, $message_content);
        }
    }

    //Display the validation errors
    if (!empty($validation_messages)) {
        foreach ($validation_messages as $validation_message) {
            echo '<div class="validation-message">' . esc_html($validation_message) . '</div>';
        }
    }
?>

    <!-- Echo a container used that will be used for the JavaScript validation -->
    <div id="validation-messages-container"></div>

    <form id="contact-form" action="<?php echo esc_url(get_permalink()); ?>" method="post">
        <input type="hidden" name="contact_form">
        <div class="input-wrapp">
            <input type="text" id="full-name" name="full_name" placeholder="Name">
        </div>
        <div class="input-wrapp">
            <input type="text" id="email" name="email" placeholder="Email">
        </div>
        <div class="input-wrapp">
            <textarea id="message" name="message" placeholder="Write something..."></textarea>
        </div>
        <button type="submit" id="contact-form-submit">
            <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path fill-rule="evenodd" clip-rule="evenodd" d="M1.81818 4.85279L9.39603 11.5887C9.74047 11.8948 10.2595 11.8948 10.604 11.5887L18.1818 4.85279V15.4547C18.1818 15.9567 17.7748 16.3637 17.2727 16.3637H2.72727C2.22519 16.3637 1.81818 15.9567 1.81818 15.4547V4.85279ZM3.1865 3.63647H16.8134L9.99995 9.69288L3.1865 3.63647Z" fill="white" />
            </svg>
            Submit Message
        </button>
    </form>

    <div id="success-messages-container"></div>
<?php
}

add_action('wp_ajax_display_contact_form', 'display_contact_form');
add_action('wp_ajax_nopriv_display_contact_form', 'display_contact_form');

JavaScript代码

$("#submit").click(function (event) {
    event.preventDefault();
    var userName = $("#full-name").val();
    var userEmail = $("#email").val();
    var userMessage = $("#message").val();
    var formData = $("#contact-form").val();
    $.ajax({
      type: "POST",
      dataType: "html",
      url: "/wp-admin/admin-ajax.php",
      data: {
        action: "display_contact_form",
        contact_form: formData,
        full_name: userName,
        email: userEmail,
        message: userMessage,
      },
      success: function (response) {
        console.log(response);
        $("#success-messages-container").append(
          "<p>Your message has been successfully delivered</p>"
        );
      },
    });
  });

解决方案

问题核心在于当前AJAX响应返回的是整个表单HTML,JS无法区分是否存在验证错误。需要将AJAX处理逻辑和表单渲染逻辑拆分,返回JSON格式的状态数据,让JS根据状态判断显示内容。

步骤1:修改PHP代码,拆分AJAX处理与表单渲染

将原有的display_contact_form拆分为短码渲染函数和AJAX处理函数,AJAX函数返回JSON:

add_shortcode('contact-form', 'display_contact_form');

// 表单渲染函数,仅负责输出表单HTML
function display_contact_form() {
?>
    <div id="validation-messages-container"></div>

    <form id="contact-form" action="<?php echo esc_url(get_permalink()); ?>" method="post">
        <input type="hidden" name="contact_form">
        <div class="input-wrapp">
            <input type="text" id="full-name" name="full_name" placeholder="Name">
        </div>
        <div class="input-wrapp">
            <input type="text" id="email" name="email" placeholder="Email">
        </div>
        <div class="input-wrapp">
            <textarea id="message" name="message" placeholder="Write something..."></textarea>
        </div>
        <button type="submit" id="contact-form-submit">
            <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path fill-rule="evenodd" clip-rule="evenodd" d="M1.81818 4.85279L9.39603 11.5887C9.74047 11.8948 10.2595 11.8948 10.604 11.5887L18.1818 4.85279V15.4547C18.1818 15.9567 17.7748 16.3637 17.2727 16.3637H2.72727C2.22519 16.3637 1.81818 15.9567 1.81818 15.4547V4.85279ZM3.1865 3.63647H16.8134L9.99995 9.69288L3.1865 3.63647Z" fill="white" />
            </svg>
            Submit Message
        </button>
    </form>

    <div id="success-messages-container"></div>
<?php
}

// AJAX处理函数,返回JSON数据
add_action('wp_ajax_contact_form_submit', 'contact_form_submit');
add_action('wp_ajax_nopriv_contact_form_submit', 'contact_form_submit');

function contact_form_submit() {
    $response = [
        'success' => false,
        'messages' => []
    ];

    if (isset($_POST['contact_form'])) {
        // 数据清理
        $full_name = isset($_POST['full_name']) ? sanitize_text_field($_POST['full_name']) : '';
        $email     = isset($_POST['email']) ? sanitize_text_field($_POST['email']) : '';
        $message   = isset($_POST['message']) ? sanitize_textarea_field($_POST['message']) : '';

        // 验证数据
        if (strlen($full_name) === 0) {
            $response['messages'][] = esc_html__('Please enter a valid name.');
        }

        if (strlen($email) === 0 || !is_email($email)) {
            $response['messages'][] = esc_html__('Please enter a valid email address.');
        }

        if (strlen($message) === 0) {
            $response['messages'][] = esc_html__('Please enter a valid message.');
        }

        // 无验证错误则发送邮件
        if (empty($response['messages'])) {
            $mail_to    = get_option('admin_email');
            $subject = 'New message from ' . $full_name;
            $message_content = $message . ' - The email address of the customer is: ' . $email;

            // 检查邮件是否发送成功
            if (wp_mail($mail_to, $subject, $message_content)) {
                $response['success'] = true;
                $response['messages'][] = esc_html__('Your message has been successfully delivered');
            } else {
                $response['messages'][] = esc_html__('Failed to send message, please try again later.');
            }
        }
    }

    // 返回JSON响应
    wp_send_json($response);
}

步骤2:修改JavaScript代码,处理JSON响应

修正JS中的选择器错误(原代码用#submit但表单按钮ID是#contact-form-submit),并根据返回的JSON状态显示对应信息:

$("#contact-form-submit").click(function (event) {
    event.preventDefault();
    
    // 清空之前的提示
    $("#validation-messages-container").empty();
    $("#success-messages-container").empty();

    var userName = $("#full-name").val();
    var userEmail = $("#email").val();
    var userMessage = $("#message").val();

    $.ajax({
        type: "POST",
        dataType: "json",
        url: "/wp-admin/admin-ajax.php",
        data: {
            action: "contact_form_submit",
            contact_form: true,
            full_name: userName,
            email: userEmail,
            message: userMessage,
        },
        success: function (response) {
            if (response.success) {
                // 显示成功提示
                $("#success-messages-container").append('<p>' + response.messages[0] + '</p>');
                // 可选:清空表单
                $("#contact-form")[0].reset();
            } else {
                // 显示验证错误
                response.messages.forEach(function(msg) {
                    $("#validation-messages-container").append('<div class="validation-message">' + msg + '</div>');
                });
            }
        },
        error: function() {
            // 处理AJAX请求失败的情况
            $("#validation-messages-container").append('<div class="validation-message">Oops, something went wrong. Please try again.</div>');
        }
    });
});

关键改进点

  1. 拆分逻辑:将表单渲染和AJAX处理分离,避免AJAX返回冗余的HTML,只返回必要的状态数据。
  2. JSON响应:用wp_send_json()返回标准JSON格式,便于JS解析状态和消息。
  3. 错误处理:JS根据success字段判断显示成功或错误信息,同时处理AJAX请求失败的情况。
  4. 修复BUG:原PHP代码中邮件内容错误地使用了$mail(管理员邮箱),改为$email(用户提交的邮箱);原JS选择器错误,修正为匹配按钮ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:45:35