Chrome sendrequest 错误:TypeError:将循环结构转换为 JSON

新手上路,请多包涵

我有以下…

chrome.extension.sendRequest({
  req: "getDocument",
  docu: pagedoc,
  name: 'name'
}, function(response){
  var efjs = response.reply;
});

它调用以下..

case "getBrowserForDocumentAttribute":
  alert("ZOMG HERE");
  sendResponse({
    reply: getBrowserForDocumentAttribute(request.docu,request.name)
  });
  break;

但是,我的代码永远不会到达“ZOMG HERE”,而是在运行 chrome.extension.sendRequest 时引发以下错误

 Uncaught TypeError: Converting circular structure to JSON
 chromeHidden.JSON.stringify
 chrome.Port.postMessage
 chrome.initExtension.chrome.extension.sendRequest
 suggestQuery

有谁知道是什么原因造成的?

原文由 Skizit 发布,翻译遵循 CC BY-SA 3.0 许可协议

阅读 839
2 个回答

这意味着您在请求中传递的对象(我猜它是 pagedoc )具有循环引用,例如:

 var a = {};
 ab = a;

JSON.stringify 不能像这样转换结构。

注意:DOM 节点就是这种情况,它们具有循环引用,即使它们没有附加到 DOM 树。每个节点都有一个 ownerDocument ,它在大多数情况下引用 documentdocument 至少通过 document.body 引用了 DOM 树,而 document.body.ownerDocument 又引用回了 document ,这只是 DOM 树中的多个循环引用 _之一_。

原文由 Felix Kling 发布,翻译遵循 CC BY-SA 3.0 许可协议

根据 Mozilla 的 JSON 文档JSON.stringify 有第二个参数 replacer 可用于在解析树时过滤/忽略子项。但是,也许您可以避免循环引用。

在 Node.js 中我们不能。所以我们可以这样做:

 function censor(censor) {
  var i = 0;

  return function(key, value) {
    if(i !== 0 && typeof(censor) === 'object' && typeof(value) == 'object' && censor == value)
      return '[Circular]';

    if(i >= 29) // seems to be a harded maximum of 30 serialized objects?
      return '[Unknown]';

    ++i; // so we know we aren't using the original object anymore

    return value;
  }
}

var b = {foo: {bar: null}};

b.foo.bar = b;

console.log("Censoring: ", b);

console.log("Result: ", JSON.stringify(b, censor(b)));

结果:

 Censoring:  { foo: { bar: [Circular] } }
Result: {"foo":{"bar":"[Circular]"}}

不幸的是,在它自动假定它是循环的之前似乎最多有 30 次迭代。否则,这应该有效。我什至 从这里 使用了 areEquivalent ,但是 JSON.stringify 在30次迭代后仍然抛出异常。尽管如此,如果您真的需要它,它足以在顶层获得对象的体面表示。也许有人可以对此进行改进?在 HTTP 请求对象的 Node.js 中,我得到:

 {
"limit": null,
"size": 0,
"chunks": [],
"writable": true,
"readable": false,
"_events": {
    "pipe": [null, null],
    "error": [null]
},
"before": [null],
"after": [],
"response": {
    "output": [],
    "outputEncodings": [],
    "writable": true,
    "_last": false,
    "chunkedEncoding": false,
    "shouldKeepAlive": true,
    "useChunkedEncodingByDefault": true,
    "_hasBody": true,
    "_trailer": "",
    "finished": false,
    "socket": {
        "_handle": {
            "writeQueueSize": 0,
            "socket": "[Unknown]",
            "onread": "[Unknown]"
        },
        "_pendingWriteReqs": "[Unknown]",
        "_flags": "[Unknown]",
        "_connectQueueSize": "[Unknown]",
        "destroyed": "[Unknown]",
        "bytesRead": "[Unknown]",
        "bytesWritten": "[Unknown]",
        "allowHalfOpen": "[Unknown]",
        "writable": "[Unknown]",
        "readable": "[Unknown]",
        "server": "[Unknown]",
        "ondrain": "[Unknown]",
        "_idleTimeout": "[Unknown]",
        "_idleNext": "[Unknown]",
        "_idlePrev": "[Unknown]",
        "_idleStart": "[Unknown]",
        "_events": "[Unknown]",
        "ondata": "[Unknown]",
        "onend": "[Unknown]",
        "_httpMessage": "[Unknown]"
    },
    "connection": "[Unknown]",
    "_events": "[Unknown]",
    "_headers": "[Unknown]",
    "_headerNames": "[Unknown]",
    "_pipeCount": "[Unknown]"
},
"headers": "[Unknown]",
"target": "[Unknown]",
"_pipeCount": "[Unknown]",
"method": "[Unknown]",
"url": "[Unknown]",
"query": "[Unknown]",
"ended": "[Unknown]"
}

我在这里创建了一个小的 Node.js 模块来执行此操作: https ://github.com/ericmuyser/stringy 随时改进/贡献!

原文由 Eric 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题