Using jQuery AJAX to host JSON for CFC

I'm trying to use jQuery / AJAX / JSON with CFC to send an email (easy?) After spending many hours trying to find one complete example of how this should work, I get closer, but am stuck in the last part. My failure is obvious.

I get the error "Unsupported operation. Check the application log for more details." return from (think) ColdFusion.

The GET request that generates this message comes from the following URL:

http://www.dumbass.com/CFIDE/componentutils/cfcexplorer.cfc?method=getcfcinhtml&name=blah.www.test&path=/blah/www/test.cfc 

I can call my CFC in a browser that sends a basic test email:

 http://servername/test.cfc?method=sendMail 

A form message in CFC is sent as such:

 method=sendMail&name=BOB&email=bob%40bitchin.com&subject=Message+from+contact+form&message=bob+is+really+bitchin 

Here 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"); } } }); 

Here is the CFC (don't even try to use form fields):

  <cfcomponent output="false" access="remote"> <cffunction name="sendMail" access="remote" returntype="void"> <cfmail from=" do-not-reply@dumbass.com " to=" illiquent@gmail.com " subject="duh!!!"> You got mail! </cfmail> </cffunction> 

AJAX returns the HTML code generated for the error message: "Unsupported operation. Check the application log for more details."

I am on a shared CF machine and do not have access to application logs. It transmits data in the form of JSON, what causes me grief? Should I use serialize () in the form instead?

In jQuery AJAX, I have test.cfc?method=sendMail . Should I put a method in an "AJAX" data block?

I have fiddler installed and I'm looking at the headers, but I'm still at a loss why sending data to CFC via jQuery and AJAX should be so cryptic.

If someone can correct me or point out a working example, I would be very grateful.

UPDATE

After looking at my javascript, I saw that I had another function called by the submit form - which called "Check the application log for more details." Here is the function that was causing the problem to me:

  $(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"); } }); }); }); 

Here is my updated CFC that "works":

  <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=" do-not-reply@dumbass.com " to=" me@dumbass.com " subject="#subject#"> Owning it! #name# #subject# #email# #message# </cfmail> <cfset result ='{"sent":"yes"}'> <cfreturn result /> </cffunction> 

The last bit I am struggling with is to correctly allow the use of returntype = "json" and how to create a return value for this. I have returntype="any" because I was getting an error when I had returntype="json" . I would like to use returntype = "json". However, this:

 <cfset result ='{"sent":"yes"}'> <cfreturn result /> 

causes an error. What is the correct way to create a similar structure, so I can use returntype = "json"? I am sure that in the future I will want to return JSON from CFC and do not want you to build the lines manually ... if that makes sense.

t

 <cfif success> <cfset result ='{"sent":"yes"}'> <cfelse> <cfset result ='{"sent":"no"}'> </cfif> 

How can I make the "result" such that I can use returntype = "json"?

+5
source share
2 answers

Instead of test.cfc, use the test.cfm page. Here is the code for it:

 <cfswitch expression="#url.method#"> <cfcase value="sendMail"> <cfmail from=" do-not-reply@dumbass.com " to=" illiquent@gmail.com " subject="duh!!!"> You got mail! </cfmail> <cfset result = structNew()> <cfset result['sent'] = true /> <cfoutput>#SerializeJSON(result)#</cfoutput> </cfcase> </cfswitch> 

you also need to tweak javascript a bit

the call should be

 url: "test.cfm?method=sendMail", 

and instead

 if (data.sent == "yes") { 

you need

 if (data.sent) { 
+3
source

no need to create lines manually

Yes, definitely don't roll your JSON. However, do not confuse returnType and returnFormat . returnType - type of the returned object, for example, query, structure, array, etc. What you are thinking about is returnFormat, which controls how the object is returned to the caller: json, wddx, or plain.

Although you can also use returnFormat in the function signature, I prefer to omit any formats from the signature and keep the function flexible. Since you ultimately want to return the structure, use this as the return type of the function (and the descriptor formatting in your ajax call).

  <cffunction name="sendMail" access="remote" returntype="struct"> 

Just be careful with key names when creating the result structure. Unfortunately, CF converts all key names to uppercase by default. This means that the javascript variable will be data.SENT instead of data.SENT . To save this case, use an associative array entry instead. (Note: the example returns a boolean value, i.e. true / false, not a string);

  <!--- Default behavior upper cases key names, ie {"SENT": true} ---> <cfset resultStruct = {sent = true} > <!--- Preserves key name case, ie {"sent": true} ---> <cfset resultStruct["sent"] = true > 

Then, if you want to return the results as JSON, just add "returnFormat = JSON" as the url parameter to your ajax call. This parameter tells CF to automatically convert the result (i.e., the Structural Object) to a JSON string:

 url: "test.cfc?method=sendMail&returnFormat=JSON", 

Finally, in your success function, use a boolean like this:

 success: function(data) { if (data.sent) { console.log("success"); } else { console.log("failure. do something else."); } } 
+2
source

Source: https://habr.com/ru/post/1246800/


All Articles