JQuery AJAX How do I get and parse JSONP instead of JSON?

11,068

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"});
Share:
11,068
madvora
Author by

madvora

Updated on July 11, 2022

Comments

  • madvora
    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
    Kevin B over 9 years
    Please 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
    Leigh over 9 years
    In 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 use cfreturn instead of switching to cfscript.
  • madvora
    madvora over 9 years
    Kevin - 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
    Leigh over 9 years
    Functions 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
    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
    Kevin B over 9 years
    Like this: return arguments.callback & "(" & serializeJSON({formError: formError, message: message}) & ")";
  • Si8
    Si8 about 7 years
    I get an error: Uncaught SyntaxError: Unexpected token : Any idea how to fix it?