javascript - formatear - Error de solicitud de envío de Chrome: TypeError: conversión de estructura circular a JSON
json view chrome (9)
Tengo los siguientes ...
chrome.extension.sendRequest({
req: "getDocument",
docu: pagedoc,
name: ''name''
}, function(response){
var efjs = response.reply;
});
que llama a lo siguiente ..
case "getBrowserForDocumentAttribute":
alert("ZOMG HERE");
sendResponse({
reply: getBrowserForDocumentAttribute(request.docu,request.name)
});
break;
Sin embargo, mi código nunca llega a "ZOMG AQUÍ", sino que arroja el siguiente error al ejecutar chrome.extension.sendRequest
Uncaught TypeError: Converting circular structure to JSON
chromeHidden.JSON.stringify
chrome.Port.postMessage
chrome.initExtension.chrome.extension.sendRequest
suggestQuery
¿Alguien tiene alguna idea de lo que está causando esto?
Basado en la respuesta de zainengineer ... Otro enfoque es hacer una copia profunda del objeto y eliminar las referencias circulares y ajustar el resultado.
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));
Esta podría no ser una respuesta relacionada, pero este enlace Detectar y corregir referencias circulares en JavaScript podría ser útil para detectar objetos que están causando una dependencia circular.
He experimentado el mismo error al intentar generar el mensaje a continuación con jQuery. La referencia circular ocurre cuando se asignó a msg.detail.reviewerName
error a msg.detail.reviewerName
. .Val () de JQuery solucionó el problema, vea la última línea.
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
Normalmente uso el paquete circular-json npm para resolver esto.
// 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":"~"}
Recibí el mismo error con jQuery formvaliadator, pero cuando quité una console.log dentro de success: function, funcionó.
Resuelvo este problema en NodeJS como este:
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));
Según los documentos JSON en Mozilla , JSON.Stringify
tiene un segundo censor
parámetros que se puede usar para filtrar / ignorar elementos secundarios al analizar el árbol. Sin embargo, quizás puedas evitar las referencias circulares.
En Node.js no podemos. Entonces podemos hacer algo como esto:
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)));
El resultado:
Censoring: { foo: { bar: [Circular] } }
Result: {"foo":{"bar":"[Circular]"}}
Desafortunadamente, parece haber un máximo de 30 iteraciones antes de que asuma automáticamente que es circular. De lo contrario, esto debería funcionar. Incluso utilicé areEquivalent
desde aquí , pero JSON.Stringify
todavía JSON.Stringify
la excepción después de 30 iteraciones. Aún así, es lo suficientemente bueno como para obtener una representación decente del objeto en un nivel superior, si realmente lo necesita. ¿Quizás alguien pueda mejorar esto sin embargo? En Node.js para un objeto de solicitud HTTP, obtengo:
{
"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]"
}
Creé un pequeño módulo Node.js para hacer esto aquí: https://github.com/ericmuyser/stringy Siéntase libre de mejorar / contribuir!
Significa que el objeto que pasa en la solicitud (supongo que es pagedoc
) tiene una referencia circular, algo así como:
var a = {};
a.b = a;
JSON.stringify
no puede convertir estructuras como esta.
NB : Este sería el caso de los nodos DOM, que tienen referencias circulares, incluso si no están vinculados al árbol DOM. Cada nodo tiene un ownerDocument
que se refiere al document
en la mayoría de los casos. document
tiene una referencia al árbol DOM al menos a través de document.body
y document.body.ownerDocument
refiere nuevamente al document
, que es solo una de las múltiples referencias circulares en el árbol DOM.
Un enfoque es quitar el objeto y las funciones del objeto principal. Y estratificar la forma más sencilla.
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
};