Ajax 调用 ColdFusion 组件未返回数据
Ajax call to ColdFusion component not returning data
我正在尝试使用 jQuery 对 QueryData.cfc
中的 ColdFusion 组件进行 Ajax 调用
这里是 QueryData.cfc 代码:
<cfcomponent name="querydata" access="remote" hint="getting data from SQL database">
<cffunction name="QueryData_Pt" access="remote" output="false" returntype="any" returnformat="JSON">
<cfquery NAME="GrabData_Pt" DATASOURCE="#Application.PrimaryDataSource#" cachedWithin = "#CreateTimeSpan(0,0,1,0)#">
//code;
</cfquery>
<cfloop query="GrabData_Pt">
<cfset Pd_data=serializeJSON(GrabData_Pt)>
</cfloop>
<cfreturn GrabData_Pt>
</cffunction>
<cffunction name="QueryData_Pd" access="remote" returntype="any" returnformat="JSON">
<cfquery NAME="GrabData_Pd" DATASOURCE="#Application.PrimaryDataSource#" cachedWithin = "#CreateTimeSpan(0,0,1,0)#">
//code
</cfquery>
<cfloop query="GrabData_Pd">
<cfset Pd_data=serializeJSON(GrabData_Pd)>
</cfloop>
<cfreturn GrabData_Pd>
</cffunction>
<cffunction name="QueryData_Rh" returntype="any" access="remote" returnformat="JSON">
<cfquery NAME="GrabData_Rh" DATASOURCE="#Application.PrimaryDataSource#" cachedWithin = "#CreateTimeSpan(0,0,1,0)#">
//somecode
</cfquery>
<cfloop query="GrabData_Rh">
<cfset Rh_data=serializeJSON(GrabData_Rh)>
</cfloop>
<cfreturn Rh_data>
</cffunction>
</cfcomponent>
我遇到的问题是没有返回任何内容。我已经转储了组件数据,并且查询按预期工作,所以不是这样,但出于某种原因,数据正在流向我的 .cfm 文件。我确定 jQuery 有问题所以现在是代码:
var pt_var;
var pd_var;
var rh_var;
var pt_array = [];
var pd_array = [];
var rh_array = [];
$(function() {
getdatafromquery();
function getdatafromquery() {
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8", // this
dataType: "json",
url: 'QueryData.cfc',
data: {
method: 'QueryData_Pt'
}
}).done(function(pt_data) {
pt_var = pt_data;
});
}
然后我使用该数据并使用 highcharts 绘制它。我可以看到 Google Chrome DevTools 没有传递任何内容。希望很清楚我做错了什么。我是 jQuery 和 Ajax 以及 ColdFusion 的新手,所以这对我来说是一个巨大的学习曲线哈哈。非常感谢任何帮助!
编辑:
原来我没有序列化到 json。但是,既然它正在被传递,它将每个单元格作为一个单独的数组传递。这是一个例子:
DATA
:
Array(79)
0:[498]
1:[494]
2:[496]
3:[494]
4:[498]
5:[495]
这是您的查询在此处输出的方式,我就是这样做的;我定义了一个查询,以便您可以看到它是如何在循环中调用的:
<cffunction name="QueryData_Pt" access="remote" output="false" returntype="any" returnformat="JSON">
<cfset retVal = ArrayNew(1)>
<cfquery NAME="results" DATASOURCE="#Application.PrimaryDataSource#" cachedWithin = "#CreateTimeSpan(0,0,1,0)#">
SELECT DEPARTMENTNAME,DEPTID,EMPLID,WORKPHONE,FULL_NAME,EMAIL_ADDRESS,LOCATION
</cfquery>
<cfloop query="results">
<cfset temp = {} />
<cfset temp['DEPARTMENTNAME']=DEPARTMENTNAME />
<cfset temp['DEPARTMENTID']=DEPTID />
<cfset temp['EMPLID']=EMPLID />
<cfset temp['WORKPHONE']=WORKPHONE />
<cfset temp['FULL_NAME']=FULL_NAME />
<cfset temp['EMAIL_ADDRESS']=EMAIL_ADDRESS />
<cfset temp['LOCATION']=LOCATION />
<cfset ArrayAppend(retval, temp)>
</cfloop>
<cfset result = {} />
<cfset result['items'] = retVal />
<cfreturn result>
</cffunction>
在 ajax 中,我调用了 cfc,并成功地创建了一个 var x=items.data,因此我可以通过这种方式调用数据 x[0].DEPARTMENTNAME 或者如果在for 循环 for (var i = 0; i < x.length; i++)
x[i].DEPARTMENTNAME.
根据我的经验,使用远程 .cfc 方法会带来一些问题。它们调试起来有点棘手,并且会在您的 .cfc 文件中打开攻击向量,这些文件通常包含您的所有应用程序逻辑。 ACF 修复了 .cfc 文件中远程方法的几个安全问题,对我来说,允许远程调用我的应用程序逻辑是不对的。
相反,我将我的应用程序逻辑与前端分开。前端代码可从 Web 根目录访问(通常为 /project_name/www/
),而其他应用程序层将位于此目录之外 - 例如/project_name/cfusion/cfc/
或 project_name/lib/stripe/stripe.cfc
.
另一种有效的处理 ajax 请求的方法如下:我使用位于 Web 根目录内的 .cfm 文件,这些文件依次调用我的 CFC。主要好处是代码分离和调试。
这是一个示例模板,我将其命名为 /test.cfm
:
<cfscript>
setting showdebugoutput=false;
header name="Content-Type" value="application/json";
try {
param name="url.param1" type="numeric";
param name="url.param2" type="numeric";
} catch (any e) {
writeOutput(serializeJSON({
"error": "Invalid request",
"errorCode": -1
}));
abort;
}
r = {
"errorCode": 0,
"error": ""
};
try {
// create and call your cfc code here
myCFC = createObject("cfc.something").init(url.param1);
r = myCFC.doSomething();
} catch (any e) {
// insert your own error handling here
param name="errorCode" default=-1;
r.errorCode = errorCode;
r.error = e.message & " " & e.detail;
}
writeOutput(serializeJSON(r));
</cfscript>
然后,在浏览器中,您可以使用 jquery 进行 ajax 调用,如下所示:
$.ajax({
url: '/test.cfm',
type: 'get',
data: {
param1: 4,
param2: 90
},
dataType: 'json',
success: function (json) {
console.log(json);
},
error: function (xhr) {
console.log(xhr);
alert('an error occurred');
}
});
和Thor4x的回答类似,我用这个
for (i in getQuery.columnList) {
ret.q[i] = QueryColumnData(getQuery, i);
}
我循环 getQuery.columnList 并使用 QueryColumnData()
。结果是 JSON 对象的结构几乎类似于冷融合查询。除了它是数组结构 ajaxReturn.key[index]
而不是结构数组。 ajaxReturn[index].key
您可以像他们那样手动指定列,或使用 IF 过滤掉某些键。
至少在 Lucee 中(很可能是 ACF,因为 Lucee 旨在与 ACF 保持一致),像 recordcount
和 columnList
本身这样的元值不在 query.columnList
中。如果你想复制那些,你只需要在循环后手动分配。
ret.q.recordcount = getQuery.recordcount;
我正在尝试使用 jQuery 对 QueryData.cfc
中的 ColdFusion 组件进行 Ajax 调用这里是 QueryData.cfc 代码:
<cfcomponent name="querydata" access="remote" hint="getting data from SQL database">
<cffunction name="QueryData_Pt" access="remote" output="false" returntype="any" returnformat="JSON">
<cfquery NAME="GrabData_Pt" DATASOURCE="#Application.PrimaryDataSource#" cachedWithin = "#CreateTimeSpan(0,0,1,0)#">
//code;
</cfquery>
<cfloop query="GrabData_Pt">
<cfset Pd_data=serializeJSON(GrabData_Pt)>
</cfloop>
<cfreturn GrabData_Pt>
</cffunction>
<cffunction name="QueryData_Pd" access="remote" returntype="any" returnformat="JSON">
<cfquery NAME="GrabData_Pd" DATASOURCE="#Application.PrimaryDataSource#" cachedWithin = "#CreateTimeSpan(0,0,1,0)#">
//code
</cfquery>
<cfloop query="GrabData_Pd">
<cfset Pd_data=serializeJSON(GrabData_Pd)>
</cfloop>
<cfreturn GrabData_Pd>
</cffunction>
<cffunction name="QueryData_Rh" returntype="any" access="remote" returnformat="JSON">
<cfquery NAME="GrabData_Rh" DATASOURCE="#Application.PrimaryDataSource#" cachedWithin = "#CreateTimeSpan(0,0,1,0)#">
//somecode
</cfquery>
<cfloop query="GrabData_Rh">
<cfset Rh_data=serializeJSON(GrabData_Rh)>
</cfloop>
<cfreturn Rh_data>
</cffunction>
</cfcomponent>
我遇到的问题是没有返回任何内容。我已经转储了组件数据,并且查询按预期工作,所以不是这样,但出于某种原因,数据正在流向我的 .cfm 文件。我确定 jQuery 有问题所以现在是代码:
var pt_var;
var pd_var;
var rh_var;
var pt_array = [];
var pd_array = [];
var rh_array = [];
$(function() {
getdatafromquery();
function getdatafromquery() {
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8", // this
dataType: "json",
url: 'QueryData.cfc',
data: {
method: 'QueryData_Pt'
}
}).done(function(pt_data) {
pt_var = pt_data;
});
}
然后我使用该数据并使用 highcharts 绘制它。我可以看到 Google Chrome DevTools 没有传递任何内容。希望很清楚我做错了什么。我是 jQuery 和 Ajax 以及 ColdFusion 的新手,所以这对我来说是一个巨大的学习曲线哈哈。非常感谢任何帮助!
编辑:
原来我没有序列化到 json。但是,既然它正在被传递,它将每个单元格作为一个单独的数组传递。这是一个例子:
DATA
:
Array(79)
0:[498]
1:[494]
2:[496]
3:[494]
4:[498]
5:[495]
这是您的查询在此处输出的方式,我就是这样做的;我定义了一个查询,以便您可以看到它是如何在循环中调用的:
<cffunction name="QueryData_Pt" access="remote" output="false" returntype="any" returnformat="JSON">
<cfset retVal = ArrayNew(1)>
<cfquery NAME="results" DATASOURCE="#Application.PrimaryDataSource#" cachedWithin = "#CreateTimeSpan(0,0,1,0)#">
SELECT DEPARTMENTNAME,DEPTID,EMPLID,WORKPHONE,FULL_NAME,EMAIL_ADDRESS,LOCATION
</cfquery>
<cfloop query="results">
<cfset temp = {} />
<cfset temp['DEPARTMENTNAME']=DEPARTMENTNAME />
<cfset temp['DEPARTMENTID']=DEPTID />
<cfset temp['EMPLID']=EMPLID />
<cfset temp['WORKPHONE']=WORKPHONE />
<cfset temp['FULL_NAME']=FULL_NAME />
<cfset temp['EMAIL_ADDRESS']=EMAIL_ADDRESS />
<cfset temp['LOCATION']=LOCATION />
<cfset ArrayAppend(retval, temp)>
</cfloop>
<cfset result = {} />
<cfset result['items'] = retVal />
<cfreturn result>
</cffunction>
在 ajax 中,我调用了 cfc,并成功地创建了一个 var x=items.data,因此我可以通过这种方式调用数据 x[0].DEPARTMENTNAME 或者如果在for 循环 for (var i = 0; i < x.length; i++)
x[i].DEPARTMENTNAME.
根据我的经验,使用远程 .cfc 方法会带来一些问题。它们调试起来有点棘手,并且会在您的 .cfc 文件中打开攻击向量,这些文件通常包含您的所有应用程序逻辑。 ACF 修复了 .cfc 文件中远程方法的几个安全问题,对我来说,允许远程调用我的应用程序逻辑是不对的。
相反,我将我的应用程序逻辑与前端分开。前端代码可从 Web 根目录访问(通常为 /project_name/www/
),而其他应用程序层将位于此目录之外 - 例如/project_name/cfusion/cfc/
或 project_name/lib/stripe/stripe.cfc
.
另一种有效的处理 ajax 请求的方法如下:我使用位于 Web 根目录内的 .cfm 文件,这些文件依次调用我的 CFC。主要好处是代码分离和调试。
这是一个示例模板,我将其命名为 /test.cfm
:
<cfscript>
setting showdebugoutput=false;
header name="Content-Type" value="application/json";
try {
param name="url.param1" type="numeric";
param name="url.param2" type="numeric";
} catch (any e) {
writeOutput(serializeJSON({
"error": "Invalid request",
"errorCode": -1
}));
abort;
}
r = {
"errorCode": 0,
"error": ""
};
try {
// create and call your cfc code here
myCFC = createObject("cfc.something").init(url.param1);
r = myCFC.doSomething();
} catch (any e) {
// insert your own error handling here
param name="errorCode" default=-1;
r.errorCode = errorCode;
r.error = e.message & " " & e.detail;
}
writeOutput(serializeJSON(r));
</cfscript>
然后,在浏览器中,您可以使用 jquery 进行 ajax 调用,如下所示:
$.ajax({
url: '/test.cfm',
type: 'get',
data: {
param1: 4,
param2: 90
},
dataType: 'json',
success: function (json) {
console.log(json);
},
error: function (xhr) {
console.log(xhr);
alert('an error occurred');
}
});
和Thor4x的回答类似,我用这个
for (i in getQuery.columnList) {
ret.q[i] = QueryColumnData(getQuery, i);
}
我循环 getQuery.columnList 并使用 QueryColumnData()
。结果是 JSON 对象的结构几乎类似于冷融合查询。除了它是数组结构 ajaxReturn.key[index]
而不是结构数组。 ajaxReturn[index].key
您可以像他们那样手动指定列,或使用 IF 过滤掉某些键。
至少在 Lucee 中(很可能是 ACF,因为 Lucee 旨在与 ACF 保持一致),像 recordcount
和 columnList
本身这样的元值不在 query.columnList
中。如果你想复制那些,你只需要在循环后手动分配。
ret.q.recordcount = getQuery.recordcount;