如何处理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>'); } }); });
关键改进点
- 拆分逻辑:将表单渲染和AJAX处理分离,避免AJAX返回冗余的HTML,只返回必要的状态数据。
- JSON响应:用
wp_send_json()返回标准JSON格式,便于JS解析状态和消息。 - 错误处理:JS根据
success字段判断显示成功或错误信息,同时处理AJAX请求失败的情况。 - 修复BUG:原PHP代码中邮件内容错误地使用了
$mail(管理员邮箱),改为$email(用户提交的邮箱);原JS选择器错误,修正为匹配按钮ID。
内容的提问来源于stack exchange,提问作者max_herm
相关产品推荐
相关产品推荐

