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

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);
}
?>

原因分析

  1. WordPress安全与路径拦截:直接访问插件目录下的PHP文件,WordPress会因为缺少官方初始化上下文触发404机制,哪怕文件真实存在。手动引入wp-load.php的方式可能引发安全限制,或导致主题的404页面HTML混入响应,破坏JSON格式,让jQuery解析失败触发错误回调。
  2. 响应格式污染:如果PHP输出了JSON之外的内容(比如404页面代码),哪怕正确的JSON在其中,混合内容会导致dataType: "json"解析失败,触发error。
  3. 路径计算潜在问题:$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:修复直接访问插件文件的问题(不推荐,有安全风险)

如果坚持直接访问插件文件,需做以下调整:

  1. 禁止主题模板输出:在PHP文件最顶部添加define('WP_USE_THEMES', false);,防止404页面混入响应。
  2. 清理额外输出:确保PHP标签前后无空白字符,避免多余输出破坏JSON格式。
  3. 添加安全验证:比如检查请求来源是否为本站。

修改后的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 06:32:11