Javascript 防止ColdFusion使用JSON将字符串转换为数字

Javascript 防止ColdFusion使用JSON将字符串转换为数字,javascript,json,coldfusion,coldfusion-9,Javascript,Json,Coldfusion,Coldfusion 9,我有ColdFusion 9.0.1和最新的修补程序(4)。 我需要ColdFusion返回所有带引号的JSON数据(作为字符串)。我有以下问题: <cfset test = StructNew()> <cfset test.name = "1234.100"> <cfoutput>#SerializeJSON(test)#</cfoutput> 每个javascript JSON解析器都将其转换为1234.1,并且不保留尾随的0。我要么需要Co

我有ColdFusion 9.0.1和最新的修补程序(4)。 我需要ColdFusion返回所有带引号的JSON数据(作为字符串)。我有以下问题:

<cfset test = StructNew()>
<cfset test.name = "1234.100">
<cfoutput>#SerializeJSON(test)#</cfoutput>
每个javascript JSON解析器都将其转换为1234.1,并且不保留尾随的0。我要么需要ColdFusion作为字符串输出,要么需要javascript解析器来保持后面的0。有什么想法吗


这是一个简化的例子。我正在从数据库中获取这些数据。

这里有一个解决方案——尽管这是一个非常粗糙、不雅观的解决方案

您的设置:

var test = {
  name = "1234.100"
};
在前面添加一些明显的字符串会迫使值在转换为JSON时变成字符串。然后我们把这条难看的绳子扔掉

var thisIsSuchAHorribleHack = "(!@$!@$)";
test.name = thisIsSuchAHorribleHack & test.name;
var serializedTest = SerializeJSON(test);
serializedTest = Replace(serializedTest, thisIsSuchAHorribleHack, "", "ALL");
writeOutput(serializedTest);

只需在数字的开头添加一个简单的空格。 最后我试着做了,但没有成功

<cfset test = StructNew()>
<cfset test.name = " 1234.100">
<cfoutput>#SerializeJSON(test)#</cfoutput>

如果不想使用乱码,可以使用正确编码JSON的第三方库。我使用了来自的JSONUtil。我使用的是ColdFusion 9,所以我不知道最近版本的ColdFusion是否修复了一些编码异常。

我知道这个问题很老了,但作为一名新的CF开发人员,我遇到了同样的问题,虽然我成功地使用了上面的“字符串破解”,最后,我从冷聚变文件中找到了一个更合适的解决方案

'Adobe ColdFusion(2016版)更新2允许您为结构中的键指定数据类型信息。这就是所谓的元数据。”

<cfscript>
   example = structnew();
   example.firstname = "Yes";
   example.lastname = "Man";
   writeoutput("<b>After serialization</b>:");
   // change the JSON key firstname to fname 
   metadata = {firstname: {type:"string",name:"fname"}};
   example.setMetadata(metadata);
   writeoutput(SerializeJSON(example));
</cfscript>

示例=structnew();
example.firstname=“是”;
example.lastname=“Man”;
writeoutput(“序列化后:”);
//将JSON密钥firstname更改为fname
元数据={firstname:{type:“string”,name:“fname”};
例如,setMetadata(元数据);
writeoutput(序列化JSON(示例));

虽然示例显示修改字符串“Yes”的元数据以保留字符串,而不是转换为布尔值,但它同样适用于将数字转换为字符串以进行JSON序列化

如果您有一个变量数组,希望将其视为字符串(例如邮政跟踪号码“9449311899561067336896”),则可能会遇到ColdFusion认为字符串看起来像数字的问题。ColdFusion可能会尝试将字符串转换为整数,但如果字符串对于整数来说太长,则可能会导致错误。当字符串来自反序列化JSON中的数组时,可能会发生这种情况

您可能认为可以使用如下字符串:

<cfset trackIdXml = "" />   
<!--- Loop through all tracking numbers and build the XML --->
<cfloop array="#trackingNumsArray#" index="i">          
    <cfset trackIdXml &= "<TrackID ID=""" />
    <cfset trackIdXml &= #trackingNumsArray[i]# />
    <cfset trackIdXml &= """/>" />
</cfloop>
trackIdXml
变量是在cfscript标记内部创建的,但仍然可以像其他Coldfusion变量一样使用,例如在cfreturn

下面是一个完整的真实示例,要求将类似整数的字符串保留为字符串。这是一个函数,它接受USPS跟踪号数组,并从USPS的API返回程序包状态响应:

<cfcomponent>
    <cffunction name="uspsLookup" access="remote" returntype="string" returnformat="plain" output="yes">
        <cfargument name="trackingNums" type="string" required="yes" />
        <cfset trackingNumsArray = DeserializeJSON(trackingNums, true) />

        <cfscript>
            trackIdXml = createObject("java",  "java.lang.StringBuffer").init();

            for (trackingNum in trackingNumsArray) {
                trackIdXml.append('<TrackID ID="');
                trackIdXml.append(#trackingNum#);
                trackIdXml.append('"/>');
            }
        </cfscript>
        
        <cfset userid = "XXXXXXXXXXXX" />
        
        <cfhttp
        method="GET"
        url='http://production.shippingapis.com/ShippingAPI.dll?API=TrackV2&XML=<TrackRequest USERID="#userid#">#trackIdXml#</TrackRequest>'>
        </cfhttp>
        
        <cfif #cfhttp.Statuscode# IS "200 OK" >
            <cfreturn "#cfhttp.Filecontent#">
        <cfelse>
            <cfreturn "error||#cfhttp.Statuscode#">
        </cfif>  
    </cffunction>
</cfcomponent>

trackIdXml=createObject(“java”,“java.lang.StringBuffer”).init();
用于(TrackingNumArray中的trackingNum){
trackIdXml.append(“”);
}

用xml实体替换0不确定这是否有效,但Ben Nadel在GitHub上有一个项目,我听说它非常有效。如果在值前面加一个空格,CF在将其转换为json时应将其保留为字符串:
。这仍然不是理想的,但可能会给你一些工作的东西,确实有效,但这是一个难题。我决定使用第三方json编码器/解码器。是的,这就是答案。这是否适用于旧版本的CF?我在CF2016中有开发和登台,但live给了我与上面相同的问题和CF10(我认为)。很难调试和跟踪。
<cfset trackIdXml = "" />   
<!--- Loop through all tracking numbers and build the XML --->
<cfloop array="#trackingNumsArray#" index="i">          
    <cfset trackIdXml &= "<TrackID ID=""" />
    <cfset trackIdXml &= #trackingNumsArray[i]# />
    <cfset trackIdXml &= """/>" />
</cfloop>
<cfscript>
    //This variable will store the XML that is used in the API request to list each tracking number
    //We must tell ColdFusion that this is a string buffer, and use .append(). Why?
    //ColdFusion will try to convert the tracking number to a integer if we do not explicitly tell it
    //to treat it as a string.
    trackIdXml = createObject("java",  "java.lang.StringBuffer").init();

    for (trackingNum in trackingNumsArray) {
        trackIdXml.append('<TrackID ID="');
        trackIdXml.append(#trackingNum#);
        trackIdXml.append('"/>');
    }
</cfscript>
<cfcomponent>
    <cffunction name="uspsLookup" access="remote" returntype="string" returnformat="plain" output="yes">
        <cfargument name="trackingNums" type="string" required="yes" />
        <cfset trackingNumsArray = DeserializeJSON(trackingNums, true) />

        <cfscript>
            trackIdXml = createObject("java",  "java.lang.StringBuffer").init();

            for (trackingNum in trackingNumsArray) {
                trackIdXml.append('<TrackID ID="');
                trackIdXml.append(#trackingNum#);
                trackIdXml.append('"/>');
            }
        </cfscript>
        
        <cfset userid = "XXXXXXXXXXXX" />
        
        <cfhttp
        method="GET"
        url='http://production.shippingapis.com/ShippingAPI.dll?API=TrackV2&XML=<TrackRequest USERID="#userid#">#trackIdXml#</TrackRequest>'>
        </cfhttp>
        
        <cfif #cfhttp.Statuscode# IS "200 OK" >
            <cfreturn "#cfhttp.Filecontent#">
        <cfelse>
            <cfreturn "error||#cfhttp.Statuscode#">
        </cfif>  
    </cffunction>
</cfcomponent>