使用jQuery $.ajax请求返回回调函数而非数据,报ReferenceError: recapCB未定义
解决jQuery JSONP请求的ReferenceError及回调返回问题
看起来你遇到了JSONP请求的两个典型问题:回调函数未定义错误,以及没有正确获取到响应数据。让我们一步步拆解并解决:
问题根源分析
- ReferenceError: recapCB is not defined:你在调用
recapMonthDEF.always(recapCB)之后才定义recapCB变量。由于JavaScript的变量提升规则,此时recapCB只是被声明但未赋值(值为undefined),所以当尝试把它作为回调传入时就会报错。 - 返回回调函数本身而非数据:JSONP的工作原理是通过动态创建
<script>标签加载服务器返回的代码,这段代码会调用一个全局回调函数并传入数据。如果你的回调函数不在全局作用域,或者Ajax配置没有正确关联回调,服务器返回的回调调用就无法被正确执行,看起来就像是返回了回调函数本身。
修复步骤及代码示例
1. 提前定义全局回调函数
把recapCB的定义移到Ajax请求之前,并且确保它是全局可访问的(避免被局部作用域包裹):
// 先定义全局回调函数 var recapCB = function(response){ if($('#newUsers').length == 0) return; let data = response; var percent = parseFloat(parseFloat(data.percentNewSessions).toFixed(1)); var percentDiff = parseFloat((100 - percent).toFixed(1)); var sessionDuration = moment().startOf('day').seconds(data.sessionDuration).format('H:mm:ss'); $('#analitycs-session').html(data.sessions); $('#analitycs-users').html(data.users); $('#analitycs-pageviews').html(data.pageviews); $('#analitycs-sessionsPerUser').html(parseFloat(data.sessionsPerUser).toFixed(2)); $('#analitycs-sessionDuration').html(sessionDuration); $('#analitycs-newUsers').html(data.newUsers); };
2. 修正Ajax请求的JSONP配置
JSONP请求不需要设置contentType: "application/json"(因为它本质是加载脚本而非JSON数据),同时建议显式指定jsonpCallback参数来关联你的回调函数:
// 发起JSONP请求 var recapMonthDEF = $.ajax({ type: 'get', url: getAnalyticsApiURL('recapMonth'), dataType: 'jsonp', jsonpCallback: 'recapCB', // 指定回调函数名 contentType: false // 移除无效的contentType设置 });
3. 调整后续逻辑的顺序
现在回调函数已经提前定义,可以安全地绑定always回调,再处理$.when的逻辑:
recapMonthDEF.always(recapCB); $.when(lastMonthSessionsDEF, recapMonthDEF).always(function(){ $('#Dashboard-tabs-1 .toggle input[type="checkbox"]').removeAttr('disabled'); });
额外优化方案
如果你不想暴露全局回调函数,可以让jQuery自动生成回调函数名(去掉jsonpCallback配置),然后在done回调中直接处理数据,这种方式更简洁且避免全局变量污染:
var recapMonthDEF = $.ajax({ type: 'get', url: getAnalyticsApiURL('recapMonth'), dataType: 'jsonp' }); recapMonthDEF.done(function(response){ if($('#newUsers').length == 0) return; let data = response; var percent = parseFloat(parseFloat(data.percentNewSessions).toFixed(1)); var percentDiff = parseFloat((100 - percent).toFixed(1)); var sessionDuration = moment().startOf('day').seconds(data.sessionDuration).format('H:mm:ss'); $('#analitycs-session').html(data.sessions); $('#analitycs-users').html(data.users); $('#analitycs-pageviews').html(data.pageviews); $('#analitycs-sessionsPerUser').html(parseFloat(data.sessionsPerUser).toFixed(2)); $('#analitycs-sessionDuration').html(sessionDuration); $('#analitycs-newUsers').html(data.newUsers); }); $.when(lastMonthSessionsDEF, recapMonthDEF).always(function(){ $('#Dashboard-tabs-1 .toggle input[type="checkbox"]').removeAttr('disabled'); });
内容的提问来源于stack exchange,提问作者Lorenzo Catalano
相关产品推荐
相关产品推荐

