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

使用AJAX调用wp_mail()时页面仍刷新且邮件无法发送的求助

解决WordPress表单AJAX提交仍刷新的问题

问题根源

你的代码存在几个核心问题导致页面刷新且AJAX无效:

  • 未阻止表单默认提交行为:点击提交按钮时,浏览器会优先执行原生表单跳转,AJAX请求还没完成页面就刷新了
  • 函数职责混乱:display_contact_form同时负责输出表单和处理邮件,不符合AJAX的前后端分离逻辑
  • 未注册WordPress AJAX动作:WordPress需要显式注册AJAX处理函数,否则admin-ajax.php无法识别请求
  • AJAX请求未携带表单数据:原请求只传了action,没提交用户填写的姓名、邮箱等内容
  • 变量未定义:原函数中$full_name、$message直接使用会触发PHP错误

修正方案

1. 修改functions.php:拆分函数并注册AJAX动作

将表单输出、AJAX处理、脚本注册拆分为独立函数,同时添加安全验证:

// 输出表单的短代码函数
function display_contact_form() {
    ob_start();
?>
<form id="contact-form">
    <input type="hidden" name="contact_form">
    <div class="input-wrapp">
        <input type="text" id="full-name" name="full_name" placeholder="Name" required>
    </div>
    <div class="input-wrapp">
        <input type="email" id="email" name="email" placeholder="Email" required>
    </div>
    <div class="input-wrapp">
        <textarea id="message" name="message" placeholder="Write something..." required></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>
<?php
    return ob_get_clean();
}
add_shortcode('contact_form', 'display_contact_form');

// AJAX处理邮件发送的函数
function handle_contact_form_ajax() {
    // CSRF验证
    check_ajax_referer('contact_form_nonce', 'nonce');

    // 清理并验证表单数据
    $full_name = sanitize_text_field($_POST['full_name']);
    $email = sanitize_email($_POST['email']);
    $message = sanitize_textarea_field($_POST['message']);

    // 检查必填字段
    if (empty($full_name) || empty($email) || empty($message)) {
        wp_send_json_error(['message' => '请填写所有必填字段']);
    }

    // 发送邮件
    $admin_mail = get_option('admin_email');
    $subject = 'New message from ' . $full_name;
    $mail_content = "Message: " . $message . "\n\nCustomer Email: " . $email;
    $headers = ['From: ' . $full_name . ' <' . $email . '>'];

    $mail_sent = wp_mail($admin_mail, $subject, $mail_content, $headers);

    $mail_sent ? wp_send_json_success(['message' => '消息发送成功']) : wp_send_json_error(['message' => '消息发送失败,请稍后重试']);
}
// 注册AJAX动作(支持登录/未登录用户)
add_action('wp_ajax_handle_contact_form', 'handle_contact_form_ajax');
add_action('wp_ajax_nopriv_handle_contact_form', 'handle_contact_form_ajax');

// 注册脚本并传递必要参数
function enqueue_contact_form_scripts() {
    wp_enqueue_script('contact-form-script', get_template_directory_uri() . '/script.js', ['jquery'], '1.0', true);
    // 传递PHP变量到JS
    wp_localize_script('contact-form-script', 'contactFormData', [
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('contact_form_nonce')
    ]);
}
add_action('wp_enqueue_scripts', 'enqueue_contact_form_scripts');

2. 更新script.js:阻止默认行为并传递表单数据

jQuery(document).ready(function($) {
    $('#contact-form').on('submit', function(e) {
        // 核心:阻止表单默认提交跳转
        e.preventDefault();

        const submitBtn = $('#contact-form-submit');
        const originalText = submitBtn.html();
        // 禁用按钮防止重复提交
        submitBtn.prop('disabled', true).html('发送中...');

        // 收集表单数据
        const formData = {
            action: 'handle_contact_form',
            nonce: contactFormData.nonce,
            full_name: $('#full-name').val(),
            email: $('#email').val(),
            message: $('#message').val()
        };

        $.ajax({
            type: 'POST',
            url: contactFormData.ajaxUrl,
            data: formData,
            dataType: 'json',
            success: function(res) {
                alert(res.data.message);
                $('#contact-form')[0].reset();
            },
            error: function(res) {
                alert(res.responseJSON.data.message);
            },
            complete: function() {
                // 恢复按钮状态
                submitBtn.prop('disabled', false).html(originalText);
            }
        });
    });
});

关键注意点

  • e.preventDefault()是阻止页面刷新的核心,必须添加
  • 使用wp_localize_script传递admin-ajax.php路径,避免硬编码适配不同站点
  • 添加CSRF验证(nonce)提升安全性
  • 对用户输入进行sanitize处理,防止恶意内容注入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:25:53