Migrating from cfjaxaproxy using $.ajax() issues

I am moving old code from cfajaxproxy to using $.ajax(). And in doing so, I am having problems sending objects to a cfc. I am not sure if this is Lucee, or my lack of knowledge on how to use ajax. Here is a shortened code bit:

var o = {};
o.sellerID = _sellerID;
var js = JSON.stringify(o);

$j.ajax(
{
type: “POST”,
url: “…/admin/cfc/tools.cfc?method=getTableSchema”,
data:
{
thisData: js,
returnFormat: “json”,
},
dataType: “json”,
success: getTableSchema,
});

When Lucee recieves it, it complains that it cannot convert a String to a Struct. I tried to send just the object (which works find in cfajaxproxy) without stringy, but it posts something that is clearly not a struct.

Is there something I am missing?

OS: Rocky Linux 9
Java Version: OpenJDK 21.0.6
Tomcat Version: Tomcat 9.0.102
Lucee Version: Lucee 6.2.0.321

kinda missing a vital clue here! what does it look like?

my tarot reader is on holiday :slight_smile:

also what does your cfc look like?

Here is a snippet of the modified version so I can make it work between a cfinvoke and a ajax call. the cfargument was set to struct.

 <cffunction name="getTableSchema" access="remote" output="false" returntype="struct">
 	<cfargument name="thisData" required="true" type="any" />
 
 	<cfif isStruct(arguments.thisData) >
 		<!--- don't change it --->
 	<cfelse>
 		<cfset arguments.thisData = deserializeJSON(arguments.thisData) />	
 	</cfif>
 	<cfreturn >
 </cffunction>

The data sent before stringify was applied:

thisData[sellerID]:“MiniFireDragon”`

When I set the cfargument to struct, this is what I get back from the server:

Lucee 6.2.0.321 Error (expression)
Message 	Invalid call of the function [getTableSchema], first Argument [thisData] is of invalid type, Cannot cast String [{"sellerID":"MiniFireDragon"}] to a value of type [struct]

the json passed (as it indicate in the error):

thisData:‘{“sellerID”:“MiniFireDragon”}’

this is my test.cfc

component remote="true"{
	remote function test( asString, asObject ) returnFormat="json" {
		systemOutput(arguments, true);
		return arguments.toJson();
	}
}

and my index.cfm


<cfscript>
  if (cgi.REQUEST_METHOD eq "post"){
    echo(form.toJson());
    abort;
  } 
</cfscript>
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>

<script>
  var o = {};
  o.sellerID = "lucee";
  o.name ="zac";
  var js = JSON.stringify(o);

  var endpoints = ["/ajax/index.cfm", "/ajax/test.cfc?method=test"];

  for (i=0; i < endpoints.length; i++ ){

    test(endpoints[i]);
  }

  function test(e){
    document.write("<h1>" +e+ "</h1>");
    $.ajax({
      type: "POST",
      url: e,
      data:
      {
        asString: JSON.stringify(o),
        asObject: o
      },
      dataType: "json",
      success: function(data){
        console.log(e);        
        console.log(data);        
        document.write("<h1>"+ e + "</h1>" + JSON.stringify(data));
      },
      error: function(data){
        console.error(data);
      }
    });
  }
</script>

ajax.zip (1.2 KB)

what i’m seeing is

/ajax/index.cfm
{"asString":"{\"sellerID\":\"lucee\",\"name\":\"zac\"}","asObject[sellerID]":"lucee","asObject[name]":"zac","fieldnames":"asString,asObject[sellerID],asObject[name]"}
/ajax/test.cfc?method=test
"{\"asString\":\"{\\\"sellerID\\\":\\\"lucee\\\",\\\"name\\\":\\\"zac\\\"}\",\"asObject\":null,\"asObject[sellerID]\":\"lucee\",\"asObject[name]\":\"zac\"}"

and in the console

/ajax/index.cfm
ajax/:24 {asString: '{"sellerID":"lucee","name":"zac"}', asObject[sellerID]: 'lucee', asObject[name]: 'zac', fieldnames: 'asString,asObject[sellerID],asObject[name]'}asObject[name]: "zac"asObject[sellerID]: "lucee"asString: "{\"sellerID\":\"lucee\",\"name\":\"zac\"}"fieldnames: "asString,asObject[sellerID],asObject[name]"[[Prototype]]: Object
ajax/:23 /ajax/test.cfc?method=test
ajax/:24 {"asString":"{\"sellerID\":\"lucee\",\"name\":\"zac\"}","asObject":null,"asObject[sellerID]":"lucee","asObject[name]":"zac"}

and the tomcat console

{"asString":"{""sellerID"":""lucee"",""name"":""zac""}","asObject":nullValue(),"asObject[sellerID]":"lucee","asObject[name]":"zac"}

the asObject":nullValue() is a bit strange TBH, Lucee 5 does the same

image

I am still using the old style of cfc functions (as you can see), so I am not sure if what you have is the same as what I have. If I understand what are you doing, your arguments are not defined to a specific type.

As I mentioned I do not have a problem sending with it is an “any”, it is when it goes up as a json string, Lucee, for some reason cannot convert the string to a struct, and it is clearly a json formated chain, and deserializeJSON works on the string as well.

$.ajax() is old code also. Most devs switched back to plain vanilla js (or like me are in the slow process of paying off technical debt) ever since HTML5 made jQuery obsolete.

plain vanilla HTML5 JavaScript

<script>
// your code here
fetch('foo.cfm', {
	method: 'POST',
	headers: {'Content-Type': 'application/json'},
	body: JSON.stringify(o)
})
.then(result => {
	return result.json();
})
.then(data => {
	console.log(data);
});
</script>

foo.cfm

<cfscript>
data = deserializeJSON(toString(getHTTPRequestData().content));
</cfscript>