WordPress CF7 wpcf7_mail_sent动作触发后无法跳转至curl返回URL求助
错误原因排查
第一版代码失效原因
CF7表单提交走AJAX流程,wpcf7_mail_sent是后台执行的钩子,触发时WP已经输出了固定格式的AJAX响应头,此时调用wp_redirect/header会报「headers already sent」错误,直接输出JS也不会被前端解析执行,所以方案完全不可行。
第二版AJAX方案失效核心问题
- 动作名不匹配:JS请求里声明的
action:"send_this_data",但PHP钩子绑定的是send_this_account,请求根本进不到处理函数 - 参数名不匹配:JS传递表单字段用的键名是
info,PHP里用$_POST["inputs"]取值当然返回null - 缺少登录态钩子:只加了未登录用户的
wp_ajax_nopriv_*钩子,登录用户发起请求会直接返回400错误 - 响应格式处理错误:JS已经指定
datatype:"json",不需要手动调用jQuery.parseJSON解析返回值
完整修复代码
前端JS代码
document.addEventListener( 'wpcf7mailsent', function( event ) { // 阻止CF7默认的提交成功提示(可选) event.preventDefault(); var inputs = event.detail.inputs; $.ajax({ type: "POST", datatype:"json", url: jsforwp_globals_sub.ajax_url, data: { action: "send_this_data", ajax_nonce: jsforwp_globals.send_info, info: inputs, } }).done(function(msg) { if(typeof msg.redirect_url != "undefined"){ window.location.href = msg.redirect_url; }else if(typeof msg.message != "undefined"){ alert(msg.message); }else{ alert('请求失败:' + JSON.stringify(msg)); } }).fail(function(xhr, status, error) { alert('请求错误:' + error); }); });
后端PHP代码
// 同时绑定登录+未登录用户的AJAX钩子 add_action("wp_ajax_send_this_data", "action_send_curl_and_redirect"); add_action("wp_ajax_nopriv_send_this_data", "action_send_curl_and_redirect"); function action_send_curl_and_redirect() { // 先校验nonce防止恶意请求 if (!isset($_POST['ajax_nonce']) || !wp_verify_nonce($_POST['ajax_nonce'], '你的nonce校验名')) { echo json_encode(['message' => '请求非法']); wp_die(); } // 正确拿取表单数据 $save = $_POST["info"]; // 组装你要发送的curl数据 $data = $save; $url= 'http://my-url'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); curl_setopt($ch, CURLOPT_TIMEOUT, 20); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json']); $response = curl_exec($ch); // 捕获curl请求错误 if(curl_errno($ch)){ echo json_encode(['message' => '接口请求失败:' . curl_error($ch)]); curl_close ($ch); wp_die(); } curl_close ($ch); // 第二个参数传true,解析为数组而不是对象 $response_data = json_decode($response, true); // 返回数据给前端 echo json_encode($response_data); wp_die(); }
注意事项
- 把PHP代码里
你的nonce校验名替换成你之前生成jsforwp_globals.send_info时对应的nonce名称,保持一致才能校验通过 - 可以在PHP处理函数里临时加
var_dump($save);wp_die();打印参数,确认表单数据是否正常拿到 - 确保curl请求的目标接口返回的是合法JSON格式,且确实存在
redirect_url字段
内容的提问来源于stack exchange,提问作者The Blind Hawk
相关产品推荐
相关产品推荐

