Copy link to clipboard
Copied
We've got an intranet hosting web apps written in ColdFusion with some RESTful services set up to query from our databases and return JSON for the web pages. Recently, we upgraded our development server from ColdFusion 2018 to ColdFusion 2021; afterwards, our calls to the REST service began returning objects that break our Javascript. On closer examination in the network tab, the JSON is all present and properly formatted; the only difference we can see is that the 'content-type' header of the returned object is 'application/json' on our production server (still running 2018), but 'text/plain' on our development server.
We've confirmed that the RESTful services are all properly registered on the development server and that the REST API scripts, site scripts, and Javascript are all identical between the development and production servers.
See below an example function from one of our REST API scripts:
<cffunction name="getProject" access="remote" returntype="String" httpmethod="POST" restPath="project">
<!--- Arguments --->
<cfargument name="criteriaStructure" type="struct" required="yes" />
<!--- Access Check --->
<cfif not request.user.authenticated>
<cfreturn notLoggedInMessage />
</cfif>
<!--- Includes --->
<cfinclude template="/GlobalResources/globalComponents/ServerAPI/Utility/Utility.cfm" />
<cfinclude template="/GlobalResources/globalComponents/DatabaseAPI/RESEARCH_FARM_PROJECT/PROJECT.cfm" />
<!--- The Tofu --->
<cfset arguments.criteriaStructure = CRFP_PROJECT_PopulateCriteriaStructure(arguments.criteriaStructure) />
<cfreturn SerializeJSON(CRFP_PROJECT_SelectQuery(arguments.criteriaStructure), serializeQueryByColumns) />
</cffunction>
<cfheader name = "content-type" charset = "utf-8" value = "application/json">
This does not change the content type of the returned object, instead producing a 500 error.
After exploring several potential causes and solutions we resurrected the old 2018 development server and found that it returns JSON objects with the appropriate content type. Since that server is running the same RESTful services with the same APIs, the same server-side page scripts, and the same Javascript, and is even running on the same physical box as the 2021 development server, we are left to conclude that something about ColdFusion 2021 is causing this discrepancy.
We've been through the administrator panel settings several times now and have even used a text comparator tool to compare the settings between the old 2018 and the new 2021 development servers, but we can't identify any setting that may account for this. Can anyone shed any light on why this is happening?
Copy link to clipboard
Copied
What happens when you try to return a struct in JSON format?
That is, try
<cffunction name="getProject" access="remote" returntype="struct" returnformat="json" httpmethod="POST" restPath="project">
together with
<!--- Return a struct --->
<cfreturn CRFP_PROJECT_SelectQuery(arguments.criteriaStructure) />
Copy link to clipboard
Copied
When we make the alterations to the API as specified, the request continues to return with a content-type of text/plain.
Copy link to clipboard
Copied
Did you test-request have text/plain by default? In any case, you should test using a client request that contains the following header:
<cfhttpparam type="header" name="Accept" value="Application/JSON">
If you haven't yet done so (for example, in Application.cfc), you may also want to ensure that the API returns JSON. To do so, add the following header to the response:
// cfscript
cfheader(name="Content-Type", value="application/json");
<!--- cfml tag --->
<cfheader name="Content-Type" value="application/json">
Copy link to clipboard
Copied
When the REST API scripts are updated with the content-type header as specified (specifically, the cfml tag is inserted into the REST function just below the arguments), there is no change in the content-type of the request returned.
When the "Accept" header of the request is set to "Application/JSON", the request never completes and instead hangs open indefinitely, presumably because no data of type application/JSON is forthcoming. It should be noted that the calling script is not ColdFusion, but Javascript, so rather than using a cfhttpparam tag, the header is set as follows:
const response = await request
.post(url)
.setRequestHeader("Accept","Application/JSON")
.send(isCriteriaStructure ? jsToCf(dataToSend) : dataToSend);
--window.pendingRequests;
return response.body;
As a further update, it should be noted that the initial advice to adjust the data returned by the API to type "struct" and to no longer serialize the JSON into text does still return content of the type text/plain, but only because what is returned is actually the contents of a server 500 error thrown by the ColdFusion server, seeming to indicate that the REST API script breaks when the indicated changes are made.