如何在WHMCS自定义供货模块中通过AJAX请求获取指定返回数据
解决WHMCS自定义供货模块AJAX请求返回整页HTML的问题
我之前在开发WHMCS自定义供货模块时也遇到过完全一样的问题!核心原因是WHMCS的ClientArea钩子函数默认会渲染整个客户区页面模板(包括头部、导航、页脚),导致你的AJAX请求拿到的不是纯JSON,而是包含页面结构的完整HTML,自然会触发JSON解析错误。下面是具体的解决步骤:
1. 后端PHP修改:跳过模板渲染,直接输出JSON
在你的qidicatedserver_ClientArea函数中,需要识别AJAX请求,处理完业务逻辑后直接输出JSON并终止程序,避免WHMCS渲染整个页面模板。
function qidicatedserver_ClientArea($vars) { // 识别AJAX请求:检查请求头+自定义action标识 $isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'; if ($isAjax && isset($_POST['qn_action']) && $_POST['qn_action'] === 'bmc') { // 这里写你的业务逻辑,生成需要返回的数据 $responseData = [ 'status' => 'success', 'data' => '你的业务数据内容', // 可以根据需求添加更多字段 ]; // 设置正确的JSON响应头 header('Content-Type: application/json; charset=utf-8'); // 输出JSON数据 echo json_encode($responseData); // 终止程序,跳过后续的模板渲染流程 exit(); } // 非AJAX请求的正常页面渲染逻辑(保持你原来的代码) return [ 'pagetitle' => '模块页面标题', 'templatefile' => 'overview', 'templateVariables' => [ // 正常页面所需的变量 ] ]; }
2. 前端AJAX代码调整:适配WHMCS请求规则
你的前端代码有两个关键问题需要修正:
- 不需要设置
contentType: "application/json",WHMCS默认用application/x-www-form-urlencoded解析POST数据,用这个格式$_POST能直接获取参数; - 必须带上WHMCS的CSRF令牌,否则请求会被拦截。
修改后的前端代码:
jQuery.ajax({ url: window.location.href, // 直接请求当前模块客户区页面URL type: "POST", data: { // 你的业务参数 qn_action: "bmc", // 带上WHMCS的CSRF令牌(在overview.tpl中通过{$csrf_token}获取) csrf_token: '{$csrf_token}' }, dataType: 'json', // 注释掉contentType,使用默认的表单编码格式 // contentType: "application/json; charset=utf-8", success: function (data, textStatus){ console.log('ldl:', data); jQuery('.powercontrol').removeClass('disabled'); jQuery(i_id).css('display', 'none'); jQuery('#powerstatus-spinner').css('display', 'none'); }, error: function(jqXHR, e) { var msg = ''; if(jqXHR.status==0){ msg = 'You are offline!!\n Please Check Your Network.'; }else if(jqXHR.status==404){ msg = 'Requested URL not found.'; }else if(jqXHR.status==500){ msg = 'Internal Server Error.<br/>'+jqXHR.responseText; }else if(e=='parsererror'){ msg = 'Error: Parsing JSON Request failed. Response content: ' + jqXHR.responseText; }else if(e=='timeout'){ msg = 'Request Time out.'; }else { msg = 'Unknown Error.<br/>'+jqXHR.responseText; } console.log('error: '+jqXHR.responseText); console.log('Error msg: '+msg); } });
关键原理说明
WHMCS的ClientArea钩子函数的设计目标是渲染客户区页面,所以当你直接返回数组时,系统会自动把数组传递给模板引擎,生成完整的HTML页面。只有当我们在识别到AJAX请求后,手动输出JSON并终止程序,才能避免页面模板的渲染,让AJAX拿到纯JSON数据。
内容的提问来源于stack exchange,提问作者user7693832
相关产品推荐
相关产品推荐

