WordPress wp_ajax请求返回400 Bad Request错误排查
WordPress AJAX联系表单400 Bad Request问题排查
问题现象
- 浏览器控制台返回错误:
400 bad request - 排查时修改
admin-ajax.php文件将响应值从0改为1,定位到报错触发的代码段如下:
if ( is_user_logged_in() ) { // If no action is registered, return a Bad Request response. if ( ! has_action( "wp_ajax_{$action}" ) ) { wp_die( '0', 400 ); }
- 暂未明确这段登录状态判断逻辑的运行机制,尝试过常规排查方式均未解决问题
- 补充信息:已知部分同类问题与主机服务商有关,当前使用主机为Hostinger,初步判断该因素与问题相关性较低
关联代码
前端Javascript代码
function formValidation() { event.preventDefault(); var name = document.forms["contactForm"]["name"].value; var email = document.forms["contactForm"]["email"].value; var subject = document.forms["contactForm"]["subject"].value; var message = document.forms["contactForm"]["message"].value; document.getElementById('status').innerHTML = ''; var errorMessage="<span class='error'>All fields are required.</span>"; var regEx = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; if (name.trim() == "" ||email.trim() == "" || subject.trim() == "" || message.trim() == "") { document.getElementById('status').innerHTML = errorMessage; return false; } if (!regEx.test(email)) { var errorMessage="<span class='error'>Invalid email.</span>"; document.getElementById('status').innerHTML = errorMessage; return false; } processContactSubmit(); return true; } function processContactSubmit() { var request = new XMLHttpRequest(); request.open("POST", "/wp-admin/admin-ajax.php?action=process_contact_form"); request.onreadystatechange = function() { if(this.readyState === 4 && this.status === 200) { document.getElementById("status").innerHTML = this.responseText; } }; var myForm = document.getElementById("contactForm"); var formData = new FormData(contactForm); request.send(formData);}
主题functions.php代码
add_action('wp_ajax_nopriv_process_contact_form', 'process_contact_form'); add_action('wp_ajax_process_contact_form', 'process_contact_form'); //Retirar essa parte para error no console, no contrario ira aparecer no navegador o numero 0. function process_contact_form() { $to = "Recipient Email Address"; $subject = $_POST["subject"]; $headers = "Testing"; $message = $_POST["message"]; $attachments = ""; $sent = wp_mail($to, $subject, $message, $headers, $attachments); if (! $sent) { echo "<span class='error'>Problem in sending mail.</span>"; } else { echo "<span class='success'>Hi, thank you for the message.</span>"; } wp_die();}
HTML表单代码
<form name="contactForm" id="contactForm" method="post" onsubmit="return formValidation()" action="">
根因说明
首先解释admin-ajax.php里那段逻辑的运行机制:WordPress的AJAX接口按用户登录状态分两套钩子:
- 已登录用户发起的AJAX请求,会匹配
wp_ajax_{自定义动作名}钩子 - 未登录用户发起的AJAX请求,会匹配
wp_ajax_nopriv_{自定义动作名}钩子
你看到的代码逻辑非常直接:如果当前请求来自已登录用户,就检查有没有对应wp_ajax_*的注册处理函数,找不到就直接返回400状态码和响应内容0。
本次400报错的核心原因有三个:
- 代码混入零宽特殊字符导致钩子注册失败:现有代码的多个关键字(如
add_action、wp_die、formValidation、document)中间夹了不可见的零宽特殊字符,直接导致PHP无法识别内置的add_action函数,你写的两行AJAX钩子注册代码完全没生效,WordPress收到请求后找不到绑定的处理函数,直接触发400报错。 - JS中FormData初始化错误:
var formData = new FormData(contactForm);里的contactForm没有被提前定义为DOM对象,属于不规范写法,多数浏览器下会直接报错,导致表单数据无法正常传递。 - 表单提交逻辑冲突:
formValidation函数开头调用了event.preventDefault()尝试阻止默认提交,但末尾又return true,会导致AJAX请求发送的同时触发表单默认同步跳转,很容易中断AJAX请求。
修复步骤
- 清除所有代码中的零宽特殊字符:不要直接复制粘贴现有代码,手动重新输入所有关键字、函数名、钩子名,重点检查前面提到的混入隐藏字符的位置,确保PHP、JS能正常识别内置方法。注意:之前修改WordPress核心文件
admin-ajax.php的操作请立刻还原,核心文件修改会在版本更新时被覆盖,还可能引发安全、兼容性问题。 - 修复JS的FormData初始化问题:将
processContactSubmit函数中的var formData = new FormData(contactForm);修改为var formData = new FormData(myForm);,用之前已经获取到的表单DOM对象初始化FormData,确保表单数据能正常发送。 - 调整表单提交逻辑:将
formValidation函数末尾的return true;修改为return false;,验证通过后仅走AJAX异步提交,阻止表单默认同步跳转,避免请求中断。 - 替换邮件配置占位符:将
functions.php中$to变量的占位符值"Recipient Email Address"替换为实际的收件人邮箱地址,避免因收件人无效导致邮件发送失败。
内容的提问来源于stack exchange,提问作者ryuunosuke.7003a
相关产品推荐
相关产品推荐

