【问题标题】:JSON.parse: unexpected non-whitespace character after JSON dataJSON.parse:JSON 数据后出现意外的非空白字符
【发布时间】:2012-04-21 10:46:41
【问题描述】:

我希望创建一个从 4 个选择菜单的选定选项派生的 JSON 对象。这些菜单可能在加载时选择了选项(由于服务器端技术),或者可能没有选择任何选项!使用 $(document).ready() 加载页面后,我的脚本就会运行……但是我遇到了 JSON 对象“JSON.parse:JSON 数据后出现意外的非空白字符”的问题

我希望我的 JSON 具有以下结构

selObj = {

    category: selectedCategory, // we can only have 1 category, this isn’t giving me a problem…

    catOptions:{
        optionValue:discountValue, // we can have many of these
        optionValue:discountValue,
        optionValue:discountValue
    },

    tariff:{
        tariffValue:discountValue, // we can have many of these
        tariffValue:discountValue
    },

    tarOptions:{
        tarOption:discountValue, // we can have many of these

    }

};

好的,这是我的函数,我在这里删除了一些项目以简化,但我将一个原始的空对象作为参数传递给函数,然后希望修改它,因为我想将 JSON 对象传递回the server if/when the select menus are changed… but for now we're just dealing with the page loading… the function also shows the values or what is selected in a dynamic table that is created using a function called defaultTable() just ignore就目前而言,它是填充我感兴趣的 JSON 对象(并且遇到问题)。

var selectMenuArray = ["cat", "catOpt", "tariff", "tariffOpt"], // these are the IDs of the select menus...     
selObj = {};

function setUpTable(selectArray, theObj){

    // okay, if we enter the page and and the user already has a tarif selected (so it is shown in the menus) we wish to show the table with the 
    // default/original values...

    var currentSelect,
        catA = [],
        catOptA = [],
        tarA = [],
        tarOptA  = [],
        catOptForObj,
        tariffForObj,
        tariffOptForObj,
        temp1 = {},
        temp2 = {},
        temp3 = {},
        i;

    // loop through the 4 menus and see what is selected
    for(i=0;i<selectArray.length;i++){
    // let's look at the options to see if any are selected by looping through the <option>
        currentSelect = document.getElementById(selectArray[i]);

        for(j=0;j<currentSelect.length;j++){
            // do we have an options with the selected attribute?
            if(currentSelect.options[j].selected == true){
                // okay, we need to make sure the table is shown then the correct values are shown?
                // we know what the Menu is... selectArray[i], and this is the text... currentSelect.options[j].
                // lets build up whet's selected in Arrays...
                switch(selectArray[i]){
                    case "cat":
                        catA.push(currentSelect.options[j].value);
                        break;
                    case "catOpt":          
                        catOptA.push(currentSelect.options[j].value);
                        catOptForObj = catOptForObj + '"' + currentSelect.options[j].value + '":"' + "% to come later" + '",';
                        break;
                    case "tariff":
                        tarA.push(currentSelect.options[j].value);
                        tariffForObj = tariffForObj + '"' + currentSelect.options[j].value + '":"' + "% to come later" + '",';
                        break;  
                    case "tariffOpt":
                        tarOptA.push(currentSelect.options[j].value);
                        tariffOptForObj = tariffOptForObj + '"' + currentSelect.options[j].value + '":"' + "% to come later" + '",';
                        break;  
                    default:
                    // no default?
                }
            }
        }
    }

    // now we can build the table
    if(catA.length > 0 || catOptA.length > 0 || tarA.length > 0 || tarOptA.length > 0){

        // show table...
        $("#dynamicTableHolder table").css("visibility","visible").hide().fadeIn('slow');

        for(i=0;i<selectArray.length;i++){  
            switch(selectArray[i]){ 
                case "cat":
                    defaultTable(catA, "dtCats");
                    theObj.cat = catA[0];
                    break;
                case "catOpt":          
                    defaultTable(catOptA, "dtTariffs");
                    temp1 = '"{' + catOptForObj.substring(0, catOptForObj.length-1).replace(/undefined/g, "")  + '}"'; 
                    theObj = jQuery.parseJSON('"catOptions":' + temp1);
                    break;
                case "tariff":
                    defaultTable(tarA, "dtCatOpts");
                    temp2 = "{" + tariffForObj.substring(0, tariffForObj.length-1).replace(/undefined/g, "") + "}";
                    //theObj = jQuery.parseJSON('"tariff":' + temp2);
                    break;  
                case "tariffOpt":
                    defaultTable(tarOptA, "dtTariffOpts");
                    temp3 = "{" + tariffOptForObj.substring(0, tariffOptForObj.length-1).replace(/undefined/g, "") + "}";
                    //theObj = jQuery.parseJSON('"tarOptions":' + temp3);
                    break;  
                default:
                // no default?
            }
        }
    }

}

我在创建 JSON 对象时遇到问题,我正在尝试在循环时连接字符串,然后使用 jQuery.parseJSON 方法将这些字符串转换为对象……但是我没有正确执行此操作。我什至尝试在创建 temp1 时更改引号。

我知道这很复杂,我可能会问很多,但谁能看出我做错了什么。我对 jQuery.parseJSON 不太熟悉,所以任何建议都会很棒,因为我觉得我快疯了!

如果我含糊不清或没有很好地解释自己,请说出来...我也把它放在小提琴上...http://jsfiddle.net/itakesmack/JSRt7/1/

请注意这是一个有效的进展,因此某些项目可能丢失或需要开发(或者我可能有其他错误......但我希望不会)。

【问题讨论】:

  • 永远不要使用字符串函数构建 JSON。在适当的对象上使用JSON.stringify()
  • 这是个好建议...我会试试的,谢谢!
  • 还记得不要在你的 JSON 中添加实际的 cmets,就好像它是 JavaScript 一样; JSON 不允许它们(除非您将它们作为对象的一部分)
  • @MikeSav:转到github.com/douglascrockford/JSON-js 并下载 json2.js 并将其包含在您的头脚本中。用法是 JSON.stringify()...
  • 进一步说明 ThiefMaster 所说的,与其尝试使用字符串来构建它,不如执行var myObj = {}; myObj["val1"] = currentSelect.options[1] 之类的操作——也就是说,从一开始就创建一个合适的对象。

标签: javascript jquery json


【解决方案1】:

您正在为 parseJSON() 提供一个看起来像 '"catOptions":"{"A":"B","C":"D",}"' 的字符串 parseJSON() 想要这样的东西 '{"catOptions":{"A":"B","C":"D"}}'

如果您要手动构建 JSON,则需要处理一些问题。

要解决您的错误,您不想将 {key:value} 括在引号中,它们会被 catOptForObj 中的引号破坏

如果您正在构建 OptForObj 字符串,您需要转义值,如果它们可能包含双引号

你基本上是这样构建你的字符串的:

s = s + '"' + A '":"' + "B" + '",';

这将产生类似"A":"B","C":"D",

逗号应该只存在于值之间。一种方法是先检查 s 是否为空,然后仅在附加值之前将其附加到 s 。比如:

s = (s.length?(s+','):'') + '"' + A + '":"' + "B" + '"';

最好是依赖内置函数,如 cmets 中建议的 JSON.stringify

【讨论】:

    【解决方案2】:

    要向使用字符串的 JSON 对象添加值。

    catOptForObj = catOptForObj + '"' + currentSelect.options[j].value + '":"' + "% to come later" + '",'; 
    

    相反,您可以尝试以下约定为 JSON 中的不同键分配值。

    catOptForObj[currentSelect.options[j].value] = "% to come later";

    【讨论】:

      猜你喜欢
      • 2018-04-25
      • 2014-03-28
      • 1970-01-01
      • 2011-11-26
      • 2011-10-09
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多