为什么我的 JSON 看起来正确但无效?

Why is my JSON invalid even though it looks correct?

我已经为此工作了很长一段时间,但我只是不明白为什么我的 JSON 无效...

JSONLint 显示此错误

    Error: Parse error on line 107:
...pair?",      "answer": "Yes, as long as the
----------------------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got 'undefined'

这是JSON

的片段
{
    "tags": "already transferred",
    "question": "Can we transfer customers who have already been transferred previously? what is the dispo? warm transfer or already contacted?",
    "answer": "Yes, mark as already contacted."
},

{
    "tags": "secured debt",
    "question": "If customer only has secured debts, can we still offer credit repair?",
    "answer": "Yes, as long as they have at least 0 in secured/unsecured debt.
    "},




    {
        "tags": "state",
        "question": "Is the program state sensitive?",
        "answer": "Yes, each partner has particular states that they service. The script engine will only offer services when the state is valid for partner who has that service."
    },

它失败了 'Yes, as long'

JSON 是在 ColdFusion 中动态创建的。

<cfscript>faqCounter=1;</cfscript>
    <CFLOOP query="getFAQs">
         <cfoutput>
            {"tags":"#getFAQs.tags#","question":"#getFAQs.question#","answer":"#getFAQs.answer#"}<cfif faqCounter<getFAQCount.getFAQPertinentCount>,</cfif>
         </cfoutput>
        <cfscript>faqCounter++;</cfscript>
    </CFLOOP>

问题是字符串包含换行符作为文字,应该是 \n。在大多数语言中,您可以将数据过滤或序列化为 JSON,它会为您处理这些转换。

考虑以下来自 https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-s/serializejson.html

的代码片段

此脚本利用 serializeJSON() 函数将数据转换为 JSON

<cfscript>
       example = structnew();
       example.firstname = "Yes";
       example.lastname = "Man";
       // changing the default serialization by specifying the type of "firstname" as string
       metadata = {firstname: {type:"string"}};
       example.setMetadata(metadata);
       writeoutput(SerializeJSON(example));
</cfscript>
{"LASTNAME":"Man","FIRSTNAME":"Yes"}

您在引号 ""

中有一个 CRLF
"answer": "Yes, as long as they have at least 0 in secured/unsecured debt.
"},

( 正如其他答案已经指出的那样,问题是未转义的新行打破了 JSON。这是避免 DIY [=50= 的原因之一]. 相反,使用内置函数 SerializeJSON(). )

Lucee 5.2.8.39+

尝试对 JSON serialization-related settings in the Application.cfc 的新支持。新设置让您可以覆盖 CF 用于序列化查询对象的奇怪默认值:

// serialize queries as an array of structures AND
// preserves the column name case used in the sql
this.serialization.preserveCaseForStructKey = true;
this.serialization.serializeQueryAs = "struct";

现在您可以跳过所有查询循环。只需执行查询并调用 serializeJSON( yourQuery ),即可生成一个看起来非常正常的字符串,如下所示:

[
  {
    "answer": "Yes, mark as already contacted.",
    "tags": "already transferred",
    "question": "Can we transfer customers who have already been transferred previously? what is the dispo? warm transfer or already contacted?"
  },
  {
    "answer": "Yes, as long as they have at least 0 in secured/unsecured debt.  ",
    "tags": "secured debt",
    "question": "If customer only has secured debts, can we still offer credit repair?"
  }
]

Lucee 早期版本

对于早期版本,执行 @Barmar recommended. Build an array of structures. Then use serializeJSON 将数组转换为格式正确的 JSON 字符串。

Runnable Example

   <cfset yourArray = []>

   <cfloop query="getFAQs">
      <cfset yourArray.append( { "tags" : getFAQs.tags
                               , "question" : getFAQs.question
                               , "answer": getFAQs.answer
                             } )>    
   </cfloop>

   <cfset jsonString = serializeJSON( yourArray )>

如何删除新行?

生成 "proper" JSON 字符串后,运行 生成 replace() 并用空字符串替换 \n

  <cfset jsonString  = replace(jsonString , "\n", "", "all")>

要永久删除它们,您首先必须找到将它们插入数据库的代码,然后在那里进行修改。此外,更新任何现有的数据库记录以删除“\n”。