我正在尝试使用 Jquery/AJAX/JSON 和 CFC 来发送电子邮件(很简单吧?)在花了很多时间试图找到一个完整的示例来说明它应该如何工作之后,我已经接近了,但仍停留在最后部分。我的失败是显而易见的。
我收到错误 “不支持的操作。检查应用程序日志以获取更多详细信息。” 从(我认为)ColdFusion 返回。
生成该消息的 GET 请求来自以下 URL:
http://www.dumbass.com/CFIDE/componentutils/cfcexplorer.cfc?method=getcfcinhtml&name=blah.www.test&path=/blah/www/test.cfc
我可以在浏览器中调用我的 CFC,它会发送基本测试电子邮件:
http://servername/test.cfc?method=sendMail
寄给 CFC 的表格将按如下方式发送:
method=sendMail&name=BOB&email=bob%40bitchin.com&subject=Message+from+contact+form&message=bob+is+really+bitchin
这是 jQuery
$.ajax({
type: "POST",
url: "test.cfc?method=sendMail",
data: {
"name": $("#footer-form #name2").val(),
"email": $("#footer-form #email2").val(),
"subject": "Message from contact form",
"message": $("#footer-form #message2").val()
},
dataType: "json",
success: function(data) {
if (data.sent == "yes") {
$("#MessageSent2").removeClass("hidden");
$("#MessageNotSent2").addClass("hidden");
$(".submit-button").removeClass("btn-default").addClass("btn-success").prop('value', 'Message Sent');
$("#footer-form .form-control").each(function() {
$(this).prop('value', '').parent().removeClass("has-success").removeClass("has-error");
});
} else {
$("#MessageNotSent2").removeClass("hidden");
$("#MessageSent2").addClass("hidden");
}
}
});
这是 CFC,(甚至没有尝试使用提交的表单字段):
<cfcomponent output="false" access="remote">
<cffunction name="sendMail" access="remote" returntype="void">
<cfmail from="[email protected]"
to="[email protected]" subject="duh!!!">
You got mail!
</cfmail>
</cffunction>
AJAX 正在恢复为失败消息创建的 HTML:“不支持的操作。请检查应用程序日志以获取更多详细信息。”。
我在共享 CF 计算机上,无法访问应用程序日志。是否以 JSON 形式传递数据让我感到悲伤?我应该在表单上使用serialize() 吗?
在 AJAX Jquery 中我有
test.cfc?method=sendMail
。我应该将该方法放在 AJAX 调用的“数据”块中吗?
我已经安装了 fiddler,并且正在查看标头,但我仍然不明白为什么通过 Jquery 和 AJAX 向 CFC 提交数据应该是一个谜。
如果有人可以纠正我或向我指出一个可行的示例,我将非常感激。
更新
查看我的 javascript 之后 - 我发现表单提交也调用了一个不同的函数 - 这导致“检查应用程序日志以获取更多详细信息”。这是导致我出现问题的函数:
$(document).ready(function () {
//this function was getting called in addition to one posted
// above.
$("input#submit1").click(function(){
console.log('WTF');
console.log($('form#footer-form').serialize());
$.ajax({
type: "POST",
// this is where I wasn't specifying the method!
// it should have been test.cfc?method=sendMail
url: "test.cfc", //process to mail
// still thinking about serialize to make this flexible
data: $('form#footer-form').serialize(),
success: function(msg){
$("#thanks").html(msg) //hide button and show thank you
$("#form-content").modal('hide'); //hide popup
},
error: function(){
alert("failure");
}
});
});
});
这是我更新后的 CFC,它正在“工作”:
<cffunction name="sendMail" access="remote" returnformat="json" returntype="any">
<cfargument name="name" required="true" />
<cfargument name="subject" required="true" />
<cfargument name="email" required="true" />
<cfargument name="message" required="true" />
<cfmail from="[email protected]"
to="[email protected]" subject="#subject#">
Owning it!
#name# #subject# #email# #message#
</cfmail>
<cfset result ='{"sent":"yes"}'>
<cfreturn result />
</cffunction>
我正在努力解决的最后一点是如何正确允许使用 returntype="json" 以及如何为此创建返回值。 我有
returntype="any"
,因为当我有 returntype="json"
时出现错误。 我想使用 returntype =“json”。然而这个:
<cfset result ='{"sent":"yes"}'>
<cfreturn result />
抛出错误。创建类似结构以便我可以使用 returntype="json" 的正确方法是什么?我确信将来我会想要从 CFC 返回 JSON,并且不想手动构建字符串......如果这有意义的话。
即
<cfif success>
<cfset result ='{"sent":"yes"}'>
<cfelse>
<cfset result ='{"sent":"no"}'>
</cfif>
如何制作“结果”以便我可以使用 returntype="json"?
使用 test.cfm 页面代替 test.cfc。这是它的代码:
<cfswitch expression="#url.method#">
<cfcase value="sendMail">
<cfmail from="[email protected]"
to="[email protected]" subject="duh!!!">
You got mail!
</cfmail>
<cfset result = structNew()>
<cfset result['sent'] = true />
<cfoutput>#SerializeJSON(result)#</cfoutput>
</cfcase>
</cfswitch>
你还需要调整一下javascript
电话应该是
url: "test.cfm?method=sendMail",
而不是
if (data.sent == "yes") {
你需要
if (data.sent) {
不想手动构建字符串
是的,绝对不要自行构建 JSON。 但是,不要混淆
returnType
和 returnFormat
。 returnType 是要返回的对象的类型,例如查询、结构、数组等。你想到的是 returnFormat,它控制如何将对象返回给调用者:json、wddx 或 plain。
虽然您也可以在函数签名中使用
returnFormat
,但我的偏好是省略签名中的任何格式并保持函数的灵活性。由于您最终想要返回一个结构,因此请将其用作函数返回类型(并在 ajax 调用中处理格式设置)。
<cffunction name="sendMail" access="remote" returntype="struct">
创建结果结构时请注意键名。不幸的是,CF 默认将所有键名称转换为大写。这意味着 javascript 变量将是
data.SENT
,而不是 data.sent
。要保留大小写,请改用关联数组表示法。 (注意,该示例返回一个布尔值,即 true/false,而不是字符串);
<!--- Default behavior upper cases key names, ie {"SENT": true} --->
<cfset resultStruct = {sent = true} >
<!--- Preserves key name case, ie {"sent": true} --->
<cfset resultStruct["sent"] = true >
然后,如果您想以 JSON 形式返回结果,只需在 ajax 调用中附加“returnFormat=JSON”作为 url 参数即可。该参数指示 CF 自动将结果(即结构对象)转换为 JSON 字符串:
url: "test.cfc?method=sendMail&returnFormat=JSON",
最后,在您的 success 函数中,使用布尔值,如下所示:
success: function(data) {
if (data.sent) {
console.log("success");
}
else {
console.log("failure. do something else.");
}
}
使用返回类型String,返回格式为纯文本,并且可以通过调用SerializeJson(object)将返回的对象转换为json。
示例:
<cffunction name="sendMail" access="remote" returnformat="plain" returntype="String">
<cfset response = {send:"yes"}>
<cfreturn SerializeJson(response)>
</cffunction>