我有以下内容…
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
有人知道是什么引起的吗?
根据zainengineer的回答…另一种方法是对对象进行深度复制,去掉循环引用并对结果进行字符串化。
function cleanStringify(object) {
if (object && typeof object === 'object') {
object = copyWithoutCircularReferences([object], object);
}
return JSON.stringify(object);
function copyWithoutCircularReferences(references, object) {
var cleanObject = {};
Object.keys(object).forEach(function(key) {
var value = object[key];
if (value && typeof value === 'object') {
if (references.indexOf(value) < 0) {
references.push(value);
cleanObject[key] = copyWithoutCircularReferences(references, value);
references.pop();
} else {
cleanObject[key] = '###_Circular_###';
}
} else if (typeof value !== 'function') {
cleanObject[key] = value;
}
});
return cleanObject;
}
}
// Example
var a = {
name: "a"
};
var b = {
name: "b"
};
b.a = a;
a.b = b;
console.log(cleanStringify(a));
console.log(cleanStringify(b));
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,该元素也包含在上面的示例中。
我在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));
根据MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#issue_with_json.stringify_when_serializing_circular_references
它是一个循环json,不能直接转换。
解决方案1:
https://www.npmjs.com/package/flatted
// ESM
import {parse, stringify, toJSON, fromJSON} from 'flatted';
// CJS
const {parse, stringify, toJSON, fromJSON} = require('flatted');
const a = [{}];
a[0].a = a;
a.push(a);
stringify(a); // [["1","0"],{"a":"0"}]
解决方案2:(同样通过MDN)
https://github.com/douglascrockford/JSON-js