Ik heb het volgende …
chrome.extension.sendRequest({
req: "getDocument",
docu: pagedoc,
name: 'name'
}, function(response){
var efjs = response.reply;
});
die het volgende oproepen ..
case "getBrowserForDocumentAttribute":
alert("ZOMG HERE");
sendResponse({
reply: getBrowserForDocumentAttribute(request.docu,request.name)
});
break;
Mijn code bereikt echter nooit “ZOMG HIER”, maar laat de volgende foutmelding tijdens het uitvoeren van chrome.extension.sendRequest
Uncaught TypeError: Converting circular structure to JSON
chromeHidden.JSON.stringify
chrome.Port.postMessage
chrome.initExtension.chrome.extension.sendRequest
suggestQuery
Heeft iemand enig idee wat dit veroorzaakt?
Antwoord 1, Autoriteit 100%
Het betekent dat het object dat u in het verzoek doorgeeft (ik denk dat het pagedoc
) heeft, een cirkelvormige referentie, zoiets als:
var a = {};
a.b = a;
JSON.Stringify
kan geen structuren zoals deze converteren.
N.B.: Dit zou het geval zijn met DOM-knooppunten, die kringverwijzingen hebben, zelfs als ze niet aan de DOM-structuur zijn gekoppeld. Elke node heeft een ownerDocument
die in de meeste gevallen verwijst naar document
. document
heeft een verwijzing naar de DOM-structuur op zijn minst via document.body
en document.body.ownerDocument
verwijst terug naar document
opnieuw, wat slechts éénis van meerdere kringverwijzingen in de DOM-structuur.
Antwoord 2, autoriteit 27%
Volgens de JSON-documenten bij Mozilla, JSON.Stringify
heeft een tweede parameter censor
die kan worden gebruikt om onderliggende items te filteren/negeren tijdens het ontleden van de boom. Maar misschien kunt u de kringverwijzingen vermijden.
In Node.js kunnen we dat niet. Dus we kunnen zoiets als dit doen:
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)));
Het resultaat:
Censoring: { foo: { bar: [Circular] } }
Result: {"foo":{"bar":"[Circular]"}}
Helaas lijken er maximaal 30 iteraties te zijn voordat het automatisch aanneemt dat het circulair is. Anders zou dit moeten werken. Ik heb zelfs areEquivalent
van hiergebruikt, maar dan JSON.Stringify
genereert nog steeds de uitzondering na 30 iteraties. Toch is het goed genoeg om een fatsoenlijke weergave van het object op topniveau te krijgen, als je het echt nodig hebt. Misschien kan iemand dit echter verbeteren? In Node.js voor een HTTP-verzoekobject krijg ik:
{
"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]"
}
Ik heb hier een kleine Node.js-module voor gemaakt: https://github.com/ericmuyser/stringy Voel je vrij om te verbeteren/bij te dragen!
Antwoord 3, autoriteit 11%
Eén benadering is het verwijderen van objecten en functies van het hoofdobject. En verstrengel de eenvoudigere vorm
function simpleStringify (object){
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
};
Antwoord 4, autoriteit 8%
Normaal gebruik ik het circular-json npm-pakket om dit op te lossen.
// Felix Kling's example
var a = {};
a.b = a;
// load circular-json module
var CircularJSON = require('circular-json');
console.log(CircularJSON.stringify(a));
//result
{"b":"~"}
Opmerking: circular-json is verouderd, ik gebruik nu flatted (van de maker van CircularJSON):
// ESM
import {parse, stringify} from 'flatted/esm';
// CJS
const {parse, stringify} = require('flatted/cjs');
const a = [{}];
a[0].a = a;
a.push(a);
stringify(a); // [["1","0"],{"a":"0"}]
van: https://www.npmjs.com/package/flatted
Antwoord 5, autoriteit 3%
Gebaseerd op het antwoord van zainengineer… Een andere benadering is om een diepe kopie van het object te maken en cirkelvormige verwijzingen te strippen en het resultaat te stringen.
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));
Antwoord 6
Dit is misschien geen gerelateerd antwoord, maar deze link Cirkelverwijzingen detecteren en corrigeren in JavaScriptkan nuttig zijn om objectente detecteren die circulaire afhankelijkheid veroorzaken.
Antwoord 7
Ik los dit probleem op NodeJS als volgt op:
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));
Antwoord 8
Voor mijn geval kreeg ik die foutmelding toen ik de functie async
op mijn server gebruikte om documenten op te halen met mangoest. Het bleek dat de reden was dat ik vergat await
in te voeren voordat ik de methode find({})
aanroep. Het toevoegen van dat onderdeel loste mijn probleem op.
Antwoord 9
Ik heb dezelfde fout ondervonden toen ik het onderstaande bericht probeerde op te bouwen met jQuery. De kringverwijzing vindt plaats wanneer reviewerName
per ongeluk werd toegewezen aan msg.detail.reviewerName
. JQuery’s .val() loste het probleem op, zie laatste regel.
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
Antwoord 10
Dit werkt en vertelt u welke eigenschappen circulair zijn. Het maakt het ook mogelijk om het object te reconstrueren met de referenties
JSON.stringifyWithCircularRefs = (function() {
const refs = new Map();
const parents = [];
const path = ["this"];
function clear() {
refs.clear();
parents.length = 0;
path.length = 1;
}
function updateParents(key, value) {
var idx = parents.length - 1;
var prev = parents[idx];
if (prev[key] === value || idx === 0) {
path.push(key);
parents.push(value);
} else {
while (idx-- >= 0) {
prev = parents[idx];
if (prev[key] === value) {
idx += 2;
parents.length = idx;
path.length = idx;
--idx;
parents[idx] = value;
path[idx] = key;
break;
}
}
}
}
function checkCircular(key, value) {
if (value != null) {
if (typeof value === "object") {
if (key) { updateParents(key, value); }
let other = refs.get(value);
if (other) {
return '[Circular Reference]' + other;
} else {
refs.set(value, path.join('.'));
}
}
}
return value;
}
return function stringifyWithCircularRefs(obj, space) {
try {
parents.push(obj);
return JSON.stringify(obj, checkCircular, space);
} finally {
clear();
}
}
})();
Voorbeeld waarbij veel van de ruis is verwijderd:
{
"requestStartTime": "2020-05-22...",
"ws": {
"_events": {},
"readyState": 2,
"_closeTimer": {
"_idleTimeout": 30000,
"_idlePrev": {
"_idleNext": "[Circular Reference]this.ws._closeTimer",
"_idlePrev": "[Circular Reference]this.ws._closeTimer",
"expiry": 33764,
"id": -9007199254740987,
"msecs": 30000,
"priorityQueuePosition": 2
},
"_idleNext": "[Circular Reference]this.ws._closeTimer._idlePrev",
"_idleStart": 3764,
"_destroyed": false
},
"_closeCode": 1006,
"_extensions": {},
"_receiver": {
"_binaryType": "nodebuffer",
"_extensions": "[Circular Reference]this.ws._extensions",
},
"_sender": {
"_extensions": "[Circular Reference]this.ws._extensions",
"_socket": {
"_tlsOptions": {
"pipe": false,
"secureContext": {
"context": {},
"singleUse": true
},
},
"ssl": {
"_parent": {
"reading": true
},
"_secureContext": "[Circular Reference]this.ws._sender._socket._tlsOptions.secureContext",
"reading": true
}
},
"_firstFragment": true,
"_compress": false,
"_bufferedBytes": 0,
"_deflating": false,
"_queue": []
},
"_socket": "[Circular Reference]this.ws._sender._socket"
}
}
Om te reconstrueren roept u JSON.parse() aan en doorloopt u de eigenschappen op zoek naar de tag [Circular Reference]
. Hak dat dan af en… evalueer… het met this
ingesteld op het root-object.
Evalueer niets dat kan worden gehackt. Het is beter om string.split('.')
te doen en vervolgens de eigenschappen op naam op te zoeken om de referentie in te stellen.
Antwoord 11
In mijn geval ben ik gewoon vergeten om async/wait te gebruiken tijdens het bouwen van de route:
app.get('/products', async (req, res) => {
const products = await Product.find();
res.send(products );
});
Antwoord 12
Ik kreeg dezelfde fout met jQuery formvaliadator, maar toen ik een console.log binnen success: function verwijderde, werkte het.
Antwoord 13
Node.js v10.22.1 (de versie die draait op onze GitLab CI-server) heeft, wat ik beschouw, een foutieve kringverwijzingsdetector. De lokaal draaiende versie (v12.8.0) is slim genoeg om te weten dat het geen echte kringverwijzing is.
Ik voeg dit antwoord toe voor het geval iemand anders hetzelfde probleem heeft en hun object eigenlijk geen kringverwijzing is.
Dit was het oorspronkelijke antwoordobject:
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"
}
Het dacht dat res.email.status
hetzelfde was als res.status
. Het is slechts een tekstelement, dus niet cirkelvormig, maar de naam en waarde struikelde kennelijk de JSON.Strationify Parser op.
Ik heb de res.email
sub-object verwijderen en alles is prima. Ik probeerde onafhankelijke statussen te verzamelen en gedetailleerde berichten van alle unieke acties die werden uitgevoerd tijdens de serveroproep. Ik heb het naar het element ingeschakeld res.emailStatus
die ook in het bovenstaande voorbeeld is opgenomen.
Antwoord 14
In mijn geval gebruik ik reageer native en probeerde
te debuggen
console.log(JSON.stringify(object))
en kreeg de fout:
TypeError: Converting circular structure to JSON
Het lijkt erop dat ik het object aan de console aan de console kan krijgen door gewoon gewoon te gebruiken:
console.log(object)