JQuery AJAX How do I get and parse JSONP instead of JSON?
I have the answer.
Please note the original posted code works perfectly fine with a normal JSON response.
This is the way I got the JSONP response working.
The AJAX Call
$.ajax({
type:"GET",
//Location of the cfc
url: "http://yourFullUrl/test.cfc",
//Function name and url variables to send
data: {method:'zip_lookup', zip:zip},
//Set to JSONP here
dataType:"jsonp",
//The name of the function that's sent back
//Optional because JQuery will create random name if you leave this out
jsonpCallback:"callback",
//This defaults to true if you are truly working cross-domain
//But you can change this for force JSONP if testing on same server
crossDomain:true,
//Function run on success takes the returned jsonp object and reads values.
success: function(responseData) {
//Pulls the variables out of the response
alert(responseData.formError);
alert(responseData.message);
}
});
The CFC in Coldfusion That Runs The Query
<cffunction name="zip_lookup" access="remote" returntype="string" returnformat="plain" output="false">
<cfquery name="qZip">
Select Distinct ZipCode
From zipcodes
Where ZipCode = '#url.zip#'
</cfquery>
<!---Return an error if zip was not found--->
<cfif qZip.RecordCount EQ 0>
<cfset formError = true>
<cfset message = "Invalid Zip">
<cfelse>
<cfset formError = false>
<cfset message = "">
</cfif>
<cfoutput>
<cfscript>
<!---Important to have double quotes around the name and value. --->
<!---I missed this before --->
return '#arguments.callback#({"formError": "#formError#", "message": "#message#"});';
</cfscript>
</cfoutput>
</cffunction>
The Formatted JSONP Response
//Using the name from the jsonpCallback setting in the AJAX call
callback({"formError": "true", "message": "Invalid Zip"});
madvora
Updated on July 11, 2022Comments
-
madvora almost 2 years
Summary
I have an application that runs a search. Before allowing submit, it sends an AJAX call to a query to check for a valid zip code, then returns a JSON result which I can parse. I need to do the same thing cross-domain now and I know that I have to use the full url and JSONP format instead, but I'm not sure how to set that up.
The AJAX Call
I send a zip code that gets run through a query.if (zipLength == 5) { $.ajax({ type:"GET", //location of the cfc url: "cfc/test.cfc", //function name and url variables to send data: {method:'zip_lookup', zip:zip}, //function run on success takes the returned json object and reads values. success: function(obj) { var response = $.parseJSON(obj); if (response.formError == true) { alert(response.message); } } }); }
The CFC in Coldfusion That Runs The Query<!---Makes sure entered zip exists---> <cffunction name="zip_lookup" access="remote"> <cfquery name="qZip"> Select Distinct ZipCode From zipcodes Where ZipCode = '#url.zip#' </cfquery> <!---Return an error if zip was not found---> <cfif qZip.RecordCount EQ 0> <cfset formError = true> <cfset message = "Invalid Zip"> <cfelse> <cfset formError = false> <cfset message = ""> </cfif> <cfoutput> <cfset obj = { "formError" = formError, "message" = message } /> </cfoutput> <cfprocessingdirective suppresswhitespace="Yes"> <cfoutput> #serializeJSON(obj)# </cfoutput> </cfprocessingdirective> <cfsetting enablecfoutputonly="No" showdebugoutput="No"> </cffunction>
The JSON Response
This is what the query returns.{"message":"Invalid Zip","formError":true}
Dealing With The Response
As I have above in the AJAX success function, I can grab the formError or message variables out of the JSON response. How I can I do this with JSONP?success: function(obj) { var response = $.parseJSON(obj); if (response.formError == true) { alert(response.message); } }
-
Kevin B over 9 yearsPlease don't manually create json, create an object instead and use serializeJSON. Doing so will avoid possible JSON format errors due to the content of the strings you are placing in the json.
-
Leigh over 9 yearsIn addition, a few tips a) The function should not access the
url
scope directly. Instead, explicitly define "zip" and "callback" as cfarguments. b) Always use cfqueryparam to protect against sql injection c) Do not forget to local scope all of your function local variables and d) No need for cfoutput at the end. Just "return" the string. Since you are cfml everywhere else, may as well usecfreturn
instead of switching to cfscript. -
madvora over 9 yearsKevin - Not sure if I can I do that. Since this isn't actually JSON anymore but JSONP and more of a string, I'm not sure serializeJSON would work.
-
Leigh over 9 yearsFunctions should be self-contained. Accessing the URL scope directly makes the function less flexible. For example, if you switch the ajax call to use method=POST, the function will break. Whatever values the function requires should be explicitly defined as cfarguments. Then it will still work, regardless of where the input values are being stored.
-
Leigh over 9 years@madvora - I think Kevin's point was - use
serializeJSON
to construct the JSON string inside the callback wrapper, rather than doing it manually. -
Kevin B over 9 yearsLike this:
return arguments.callback & "(" & serializeJSON({formError: formError, message: message}) & ")";
-
Si8 about 7 yearsI get an error:
Uncaught SyntaxError: Unexpected token :
Any idea how to fix it?