WordPress中PHP发送邮件问题:页面加载后获JS文本未收到邮件
这种情况我碰过好多次——AJAX请求看着成功,邮件却不见踪影,大概率是这几个环节出了问题,咱们一步步排查:
别直接用PHP原生的mail()函数,WordPress自带的wp_mail()更适配系统环境,也更容易排查问题。很多服务器会拦截原生mail()的请求,或者要求发件人必须是站点域名内的邮箱(比如noreply@yourdomain.com,不能用随便的邮箱)。
你可以先写个简单的测试脚本,验证wp_mail本身能不能正常发信:
// 把这段代码临时加到主题的functions.php里,访问任意页面后删除 function test_wp_mail() { $to = '你的收件邮箱@example.com'; $subject = '测试邮件'; $message = '这是WordPress wp_mail的测试邮件'; $headers = array('From: 站点发件人 <noreply@yourdomain.com>'); $result = wp_mail($to, $subject, $message, $headers); error_log('邮件测试结果:' . ($result ? '成功' : '失败')); } add_action('init', 'test_wp_mail');
然后去服务器的错误日志里看结果,如果测试都失败,那问题出在服务器邮件配置,直接跳到第4点。
控制台显示请求成功,不代表PHP真的收到了正确的文本。你可以在PHP处理函数里加日志,看看接收的数据:
function your_ajax_email_function() { // 先记录所有POST数据到日志 error_log('AJAX接收的数据:' . print_r($_POST, true)); // 你的其他代码... wp_die(); }
然后去服务器日志里查看,如果text_content(假设你传的键是这个)是空的,那就是JS那边的数据传递有问题——比如生成文本的逻辑没执行完就发了AJAX,或者参数名写错了。
WordPress的AJAX请求必须绑定正确的动作钩子:
- 前台用户访问:需要同时绑定
wp_ajax_nopriv_你的动作名和wp_ajax_你的动作名 - 后台用户访问:只需要
wp_ajax_你的动作名
另外别忘了验证nonce(安全验证),如果nonce验证失败,PHP会直接终止请求,控制台可能还是显示200,但实际没执行发信逻辑。正确的nonce用法应该是:
// PHP里生成nonce wp_localize_script('你的脚本名', 'ajax_data', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('send_email_nonce') )); // AJAX处理函数里验证 check_ajax_referer('send_email_nonce', 'nonce');
很多共享主机默认禁用了邮件函数,或者默认配置的邮件服务器信誉低,邮件直接被拦截。这时候最靠谱的办法是用SMTP发信:
- 安装WP Mail SMTP插件,配置成用主机提供的SMTP服务、SendGrid、Gmail等第三方邮件服务
- 插件会自带日志功能,能清晰看到邮件发送的每一步状态,是发送失败还是被拒收
有时候邮件其实发出去了,但被收件箱的垃圾过滤器拦截了。先检查垃圾邮件文件夹,或者换个收件邮箱试试。另外给站点配置DKIM、SPF域名解析记录,能大幅提高邮件的送达率。
JS部分(放在主题的js/custom-ajax.js里)
document.addEventListener('DOMContentLoaded', function() { // 假设这是JS生成的文本 const generatedText = document.querySelector('.js-generated-text').textContent; // 发送AJAX请求 fetch(ajax_data.ajax_url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ action: 'send_generated_text', nonce: ajax_data.nonce, text_content: generatedText }) }) .then(res => res.json()) .then(data => { console.log(data.msg); }) .catch(err => console.error('请求出错:', err)); });
PHP部分(放在主题functions.php里)
// 注册脚本并传递AJAX参数 add_action('wp_enqueue_scripts', 'enqueue_custom_ajax_script'); function enqueue_custom_ajax_script() { wp_enqueue_script('custom-ajax', get_template_directory_uri() . '/js/custom-ajax.js', array('jquery'), '1.0', true); wp_localize_script('custom-ajax', 'ajax_data', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('send_email_nonce') )); } // AJAX处理函数 add_action('wp_ajax_send_generated_text', 'send_generated_text_email'); add_action('wp_ajax_nopriv_send_generated_text', 'send_generated_text_email'); function send_generated_text_email() { // 验证nonce check_ajax_referer('send_email_nonce', 'nonce'); // 接收并过滤文本 $text = isset($_POST['text_content']) ? sanitize_textarea_field($_POST['text_content']) : ''; if(empty($text)) { wp_send_json_error(array('msg' => '没有收到文本内容')); } // 发送邮件 $to = '你的收件邮箱@example.com'; $subject = 'JS生成的文本内容'; $message = "用户页面生成的文本:\n\n{$text}"; $headers = array('From: 站点通知 <noreply@yourdomain.com>'); $sent = wp_mail($to, $subject, $message, $headers); if($sent) { wp_send_json_success(array('msg' => '邮件发送成功')); } else { // 记录错误日志 error_log('邮件发送失败:' . print_r(error_get_last(), true)); wp_send_json_error(array('msg' => '邮件发送失败,请查看服务器日志')); } wp_die(); // 必须终止AJAX请求 }
先从测试wp_mail开始,再检查数据传递,大概率能找到问题所在。
内容的提问来源于stack exchange,提问作者Wojtar

