我有以下内容…

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

有人知道是什么引起的吗?


当前回答

Node.js v10.22.1(在我们的GitLab CI服务器上运行的版本)有一个我认为是错误的循环引用检测器。本地运行的版本(v12.8.0)足够智能,可以知道它不是真正的循环引用。

我添加这个响应是为了防止其他人有同样的问题,而他们的对象实际上不是循环引用。

这是原始的响应对象:

var res = {
    "status":"OK",
    "message":"Success",
    "errCode":":",
    "data":"",
    "appCfg":{
        "acp_age":"2yy",
        "acp_us":"yes",
        "mode":"admin",
        "version":"v1.21.07.1"
    },
    "reqID":59833,
    "email":{
        "status":"OK",
        "message":"Success"
    },
    "emailStatus":"sent"
}

它认为res.email.status和res.status是一样的。它只是一个文本元素,所以不是循环的,但是名称和值显然打乱了JSON。stringify解析器。

我删除了res.email子对象,一切正常。我试图从服务器调用期间执行的所有独特操作中收集独立状态和详细消息。我将其切换到元素res.emailStatus,该元素也包含在上面的示例中。

其他回答

一种方法是从主对象中剥离对象和函数。并对更简单的形式进行stringalize

function simpleStringify (object){
    // stringify an object, avoiding circular structures
    // https://stackoverflow.com/a/31557814
    var simpleObject = {};
    for (var prop in object ){
        if (!object.hasOwnProperty(prop)){
            continue;
        }
        if (typeof(object[prop]) == 'object'){
            continue;
        }
        if (typeof(object[prop]) == 'function'){
            continue;
        }
        simpleObject[prop] = object[prop];
    }
    return JSON.stringify(simpleObject); // returns cleaned up JSON
};

如果你使用node js使用inspect()(参考文档)

import {inspect} from "util";
console.log(inspect(object));

你可能做过类似的事情

<Button onClick={fetchSuggestions}>

未能意识到您已将“事件对象”传递给该函数

如果你不想传递任何东西,只需发送一个空字符串

<Button onClick={() => fetchSuggestions()}>
  const fetchSuggestions = async (propsSession) => {
    const {
      error,
      hasNextDoc,
      suggestions: moreSuggestions,
    } = await fetcher(`/admin/fetchSuggestion`, {
      initialRequest: !!propsSession,
      session: propsSession || session,
    });
  }

在尝试用jQuery构建下面的消息时,我也遇到过同样的错误。循环引用发生在reviewerName被错误地分配给msg.detail.reviewerName时。JQuery的.val()修复了这个问题,参见最后一行。

var reviewerName = $('reviewerName'); // <input type="text" id="taskName" />;
var msg = {"type":"A", "detail":{"managerReview":true} };
msg.detail.reviewerName = reviewerName; // Error
msg.detail.reviewerName = reviewerName.val(); // Fixed

我在NodeJS上是这样解决这个问题的:

var util = require('util');

// Our circular object
var obj = {foo: {bar: null}, a:{a:{a:{a:{a:{a:{a:{hi: 'Yo!'}}}}}}}};
obj.foo.bar = obj;

// Generate almost valid JS object definition code (typeof string)
var str = util.inspect(b, {depth: null});

// Fix code to the valid state (in this example it is not required, but my object was huge and complex, and I needed this for my case)
str = str
    .replace(/<Buffer[ \w\.]+>/ig, '"buffer"')
    .replace(/\[Function]/ig, 'function(){}')
    .replace(/\[Circular]/ig, '"Circular"')
    .replace(/\{ \[Function: ([\w]+)]/ig, '{ $1: function $1 () {},')
    .replace(/\[Function: ([\w]+)]/ig, 'function $1(){}')
    .replace(/(\w+): ([\w :]+GMT\+[\w \(\)]+),/ig, '$1: new Date("$2"),')
    .replace(/(\S+): ,/ig, '$1: null,');

// Create function to eval stringifyed code
var foo = new Function('return ' + str + ';');

// And have fun
console.log(JSON.stringify(foo(), null, 4));

这意味着你在请求中传递的对象(我猜是pagedoc)有一个循环引用,类似于:

var a = {};
a.b = a;

JSON。Stringify不能像这样转换结构。

注意:这将是DOM节点的情况,它们具有循环引用,即使它们没有附加到DOM树。每个节点都有一个ownerDocument,它在大多数情况下引用document。document至少通过document有一个对DOM树的引用。body和document.body. ownerdocument再次指向document,而document只是DOM树中多个循环引用中的一个。