WordPress Ajax请求返回预期数据却触发错误处理器的原因及解决方法
问题:WordPress插件Ajax调用获取到数据却触发错误处理器,返回404 HTML
我开发WordPress插件时遇到一个问题:Ajax调用确实能拿到GPT API的正确响应,但总会被错误处理器捕获,返回带HTML标记的“页面未找到(404)”错误。明明数据正常获取,为什么会被判定为错误?该怎么解决?
我的Ajax调用代码
function myAiAnnaFunction(question, answer, post_id) { jQuery.ajax({ type: "POST", url: "<?php echo plugins_url( 'includes/aiAnna/ask_ai-anna.php', dirname( __FILE__ ) ); ?>", dataType: "json", data: {"question" : question, "answer" : answer}, success: function(data) { if (data == null){ response = "Oh no, aiAnna was not able to fetch a response. Do not worry though as your credit has not been reduced! Please try again!"; } else { response = data.trim(); alert(response); } var answerOutput = document.getElementById("feedback_box_" + post_id); answerOutput.value = response; }, error: function (request, status, error) { console.log(error); console.log(request.responseText); } }); }
调用的PHP文件代码
<?php $path = preg_replace('/wp-content(?!.*wp-content).*/','',__DIR__); require($path.'wp-load.php'); function ask_ai_anna($question, $answer) { $ch = curl_init(); $url = 'https://api.openai.com/v1/chat/completions'; $api_key = 'sk-*********************************'; $post_fields = array( "model" => "gpt-3.5-turbo", "messages" => array( array( "role" => "system", "content" => "You are a helpful assistant!" ), array( "role" => "user", "content" => $question ) ) ); //"max_tokens" => 500, //"temperature" => 0.8 $header = [ 'Content-Type: application/json', 'Authorization: Bearer ' . $api_key ]; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_fields)); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error: ' . curl_error($ch); } curl_close($ch); $response = json_decode($result); $response = $response->choices[0]->message->content; return $response; } if(isset($_POST['question'])) { $question = $_POST['question']; $answer = $_POST['answer']; $dataReturn = ask_ai_anna($question, $answer); echo json_encode($dataReturn); } ?>
原因分析
- WordPress安全与路径拦截:直接访问插件目录下的PHP文件,WordPress会因为缺少官方初始化上下文触发404机制,哪怕文件真实存在。手动引入
wp-load.php的方式可能引发安全限制,或导致主题的404页面HTML混入响应,破坏JSON格式,让jQuery解析失败触发错误回调。 - 响应格式污染:如果PHP输出了JSON之外的内容(比如404页面代码),哪怕正确的JSON在其中,混合内容会导致
dataType: "json"解析失败,触发error。 - 路径计算潜在问题:
$path的计算逻辑在部分服务器环境下可能出错,导致wp-load.php引入失败,进而触发404。
解决方法
方法1:用WordPress官方Ajax API(推荐)
WordPress提供了标准化Ajax处理机制,规避直接访问文件的安全和路径问题:
步骤1:在插件主文件注册Ajax动作
// 登录/未登录用户都可访问,按需调整 add_action('wp_ajax_ask_ai_anna', 'ask_ai_anna_handler'); add_action('wp_ajax_nopriv_ask_ai_anna', 'ask_ai_anna_handler'); function ask_ai_anna_handler() { // CSRF安全验证 check_ajax_referer('ai_anna_nonce', 'nonce'); if(!isset($_POST['question'])) { wp_send_json_error(['error' => 'Invalid request']); } $question = sanitize_text_field($_POST['question']); $api_key = 'sk-*********************************'; // 建议存到WordPress选项,别硬编码 $ch = curl_init(); $url = 'https://api.openai.com/v1/chat/completions'; $post_fields = array( "model" => "gpt-3.5-turbo", "messages" => array( array("role" => "system", "content" => "You are a helpful assistant!"), array("role" => "user", "content" => $question) ) ); $header = [ 'Content-Type: application/json', 'Authorization: Bearer ' . $api_key ]; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_fields)); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); $result = curl_exec($ch); if(curl_errno($ch)) { wp_send_json_error(['error' => curl_error($ch)]); } curl_close($ch); $response = json_decode($result); if(empty($response->choices[0]->message->content)) { wp_send_json_error(['error' => 'No response from AI']); } wp_send_json_success(trim($response->choices[0]->message->content)); }
步骤2:修改前端Ajax代码
function myAiAnnaFunction(question, answer, post_id) { jQuery.ajax({ type: "POST", url: "<?php echo admin_url('admin-ajax.php'); ?>", dataType: "json", data: { "action": "ask_ai_anna", "nonce": "<?php echo wp_create_nonce('ai_anna_nonce'); ?>", "question": question, "answer": answer }, success: function(data) { let response; if(data.success) { response = data.data; } else { response = "Oh no, aiAnna was not able to fetch a response. Do not worry though as your credit has not been reduced! Please try again!"; } const answerOutput = document.getElementById("feedback_box_" + post_id); answerOutput.value = response; }, error: function(request, status, error) { console.log(error); console.log(request.responseText); } }); }
方法2:修复直接访问插件文件的问题(不推荐,有安全风险)
如果坚持直接访问插件文件,需做以下调整:
- 禁止主题模板输出:在PHP文件最顶部添加
define('WP_USE_THEMES', false);,防止404页面混入响应。 - 清理额外输出:确保PHP标签前后无空白字符,避免多余输出破坏JSON格式。
- 添加安全验证:比如检查请求来源是否为本站。
修改后的PHP文件开头:
<?php define('WP_USE_THEMES', false); $path = preg_replace('/wp-content(?!.*wp-content).*/','',__DIR__); require($path.'wp-load.php'); // 验证请求来源 if(!isset($_SERVER['HTTP_REFERER']) || strpos($_SERVER['HTTP_REFERER'], home_url()) === false) { wp_send_json_error(['error' => 'Invalid request']); } // 后续代码不变...
内容的提问来源于stack exchange,提问作者sw123456
相关产品推荐
相关产品推荐

