Chrome sendrequest error: TypeError: Converting circular structure to JSON

后端 未结 11 1052
醉梦人生
醉梦人生 2020-11-22 04:16

I\'ve got the following...

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


        
相关标签:
11条回答
  • 2020-11-22 05:05

    I normally use the circular-json npm package to solve this.

    // 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":"~"}
    

    Note: circular-json has been deprecated, I now use flatted (from the creator of 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"}]
    

    from: https://www.npmjs.com/package/flatted

    0 讨论(0)
  • 2020-11-22 05:05

    For my case I was getting that error when I was using async function on my server-side to fetch documents using mongoose. It turned out that the reason was I forgot to put await before calling find({}) method. Adding that part fixed my issue.

    0 讨论(0)
  • 2020-11-22 05:13

    As per the JSON docs at Mozilla, JSON.Stringify has a second parameter censor which can be used to filter/ignore children items while parsing the tree. However, perhaps you can avoid the circular references.

    In Node.js we cannot. So we can do something like this:

    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)));
    

    The result:

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

    Unfortunately there seems to be a maximum of 30 iterations before it automatically assumes it's circular. Otherwise, this should work. I even used areEquivalent from here, but JSON.Stringify still throws the exception after 30 iterations. Still, it's good enough to get a decent representation of the object at a top level, if you really need it. Perhaps somebody can improve upon this though? In Node.js for an HTTP request object, I'm getting:

    {
    "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]"
    }
    

    I created a small Node.js module to do this here: https://github.com/ericmuyser/stringy Feel free to improve/contribute!

    0 讨论(0)
  • 2020-11-22 05:14

    This works and tells you which properties are circular. It also allows for reconstructing the object with the references

      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();
          }
        }
      })();
    

    Example with a lot of the noise removed:

    {
        "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"
        }
    }
    

    To reconstruct call JSON.parse() then loop through the properties looking for the [Circular Reference] tag. Then chop that off and... eval... it with this set to the root object.

    Don't eval anything that can be hacked. Better practice would be to do string.split('.') then lookup the properties by name to set the reference.

    0 讨论(0)
  • 2020-11-22 05:17

    I was getting the same error with jQuery formvaliadator, but when I removed a console.log inside success: function, it worked.

    0 讨论(0)
提交回复
热议问题