Javascript 无法将JSON对象作为请求参数发送,因为JSON.stringify给出了循环引用错误

Javascript 无法将JSON对象作为请求参数发送,因为JSON.stringify给出了循环引用错误,javascript,jquery,ajax,json,Javascript,Jquery,Ajax,Json,我有一个树,显示在屏幕上,它基本上是一个JSON对象。我想将这个JSON对象作为请求参数发送到Java类 以下是JSON对象的示例: // Root node var rootNode = { Content: "Root", Nodes:[] }; // First Level rootNode.Nodes[0] = { Content: "Employee Code", navigationType: "0"}; rootNode.Nodes[1] = { Content: "Problem

我有一个树,显示在屏幕上,它基本上是一个JSON对象。我想将这个JSON对象作为
请求
参数发送到Java类

以下是JSON对象的示例:

// Root node
var rootNode = { Content: "Root", Nodes:[] };
// First Level
rootNode.Nodes[0] = { Content: "Employee Code", navigationType: "0"};
rootNode.Nodes[1] = { Content: "Problem Area", navigationType: "1" };
// Second Level
rootNode.Nodes[1].Nodes = [{ Content : "ACC-HO", Collapsed: true},
                           { Content : "ACC-SALES" },
                           { Content : "BUSI. HEAD", ToolTip: "Click ME!" },
                           { Content : "CEO"}
                          ];
现在,这个插件从JSON对象创建了这棵树,它将
父节点的引用存储在每个节点中。因此,这将导致一个
循环引用
,其中一个节点存储其子节点的引用,而每个子节点存储其父节点的引用

由于这个原因,我

我想使用Ajax将
rootNode
对象作为请求参数发送。我已经做了以下工作:

$.ajax({
    type : "POST",
    url : "treeDemo_!saveTree",
            data: {treeObject: JSON.stringify(rootNode) },
            success : function(resp) {      
        alert('success');
    }
});

但正如我提到的,JSON.stringify在我的案例中不起作用。那么,有谁能建议一种替代方法,将JSON对象作为请求参数发送给我,我可以在Java代码中接收并进一步处理它吗?

如果你不能清理插件,一个解决方案是克隆rootNode对象,在这个过程中不要复制“Parent”属性:

function goclone(source) {
    if (Object.prototype.toString.call(source) === '[object Array]') {
        var clone = [];
        for (var i=0; i<source.length; i++) {
            clone[i] = goclone(source[i]);
        }
        return clone;
    } else if (typeof(source)=="object") {
        var clone = {};
        for (var prop in source) {
            if (source.hasOwnProperty(prop) && prop!='Parent') {
                clone[prop] = goclone(source[prop]);
            }
        }
        return clone;
    } else {
        return source;
    }
}

var serializableRootNode = goclone(rootNode);
函数goclone(源代码){
if(Object.prototype.toString.call(source)='[Object Array]'){
var克隆=[];

对于(var i=0;i如果无法清除插件,则解决方案是克隆rootNode对象,并且在此过程中不要复制“Parent”属性:

function goclone(source) {
    if (Object.prototype.toString.call(source) === '[object Array]') {
        var clone = [];
        for (var i=0; i<source.length; i++) {
            clone[i] = goclone(source[i]);
        }
        return clone;
    } else if (typeof(source)=="object") {
        var clone = {};
        for (var prop in source) {
            if (source.hasOwnProperty(prop) && prop!='Parent') {
                clone[prop] = goclone(source[prop]);
            }
        }
        return clone;
    } else {
        return source;
    }
}

var serializableRootNode = goclone(rootNode);
函数goclone(源代码){
if(Object.prototype.toString.call(source)='[Object Array]'){
var克隆=[];

对于(var i=0;iYou建议通过删除对父对象的引用来更改实际对象。但是,如果我不想更改实际对象并将其原样传递给Java类,该怎么办?我将在每个节点中要求父对象引用,即使在Java类中也是如此。有什么解决方法吗?为什么要发送父引用?这意味着定义一个特殊代码描述它只是开销:你可以很容易地用java重建它。一般的规则是避免循环结构,当你无法避免它们时(这是非常罕见的),使用不同的(不是冗余的)用于所有类型的持久性的结构。谢谢@dystroy!此方法工作得非常好。但是我可以要求一件事。如果要从根节点中删除更多的属性,如
Parent
,并仅保留我使用时所需的属性,该怎么办?我尝试在相同的方法中添加一个
else if
条件,具有appr正确的属性名称。但它在
clone[prop]=goclone(source[prop]);
处给出了一个
堆栈溢出错误;
如果您只有3个或4个以上的可能属性,您可以在现有测试中简单地添加一些
&&prop!='somettr'
。请注意,如果您遵循循环链接,克隆也会导致堆栈溢出(无法使用此克隆循环结构)。太好了!它成功了。我正在尝试
else if
| prop!='someAttr'
认为它将在每个属性上循环,因此它不起作用。非常感谢!您建议通过删除对父对象的引用来更改实际对象。但是如果我不想更改实际对象并将其原样传递给Java,该怎么办类。即使在Java类中,我也需要每个节点中的父引用。有什么解决方法吗?为什么要发送父引用?这意味着定义一个特殊的代码来描述它,这只是开销:您可以很容易地在Java中重建它。一般规则是避免循环结构,以及当您无法避免它们时(非常罕见),使用不同的(非冗余)用于所有类型的持久性的结构。谢谢@dystroy!此方法工作得非常好。但是我可以要求一件事。如果要从根节点中删除更多的属性,如
Parent
,并仅保留我使用时所需的属性,该怎么办?我尝试在相同的方法中添加一个
else if
条件,具有appr正确的属性名称。但它在
clone[prop]=goclone(source[prop]);
处给出了一个
堆栈溢出错误;
如果您只有3个或4个以上的可能属性,您可以在现有测试中简单地添加一些
&&prop!='somettr'
。请注意,如果您遵循循环链接,克隆也会导致堆栈溢出(你不能用这个克隆一个循环结构)。太好了!它成功了。我当时正在尝试
else if
|prop!='someAttr'
认为它会在每个属性上循环,因此它不起作用。非常感谢!