Skip to content Skip to sidebar Skip to footer

Stringify Domwindow Object

For some reason I seem unable to use JSON.stringify on a DOMWindow object. For example: console.log(window.self); // Outputs a hierarchical DOMWindow object console.log(JSON.strin

Solution 1:

Why would you want to do serialize the DOM? If you must, Crescent's link is where you need to look. The reason you cannot serialize (stringify) the window object is because it contains circular references, and JSON.stringify does not support them by default.

Solution 2:

As others have said, stringify doesn't support circular references, which DOMWindow contains. Generally, circular references could be converted to JSON using Douglas Cockford's JSON cycle.js.

However, I just tried this on window, and it causes a stack overflow anyway. While that may be a bug in the cycle.js code, it seems like its more likely that window is just too big of an object.

Solution 3:

This answer is not mine, but I was here for the same thing and found this answer elsewhere. I don't have that page open anymore-- I do have the github page still open...

JSON.stringify deep objects -- thanks, @Bergi. https://github.com/Canop/JSON.prune

// JSON.prune : a function to stringify any object without overflow// two additional optional parameters ://   - the maximal depth (default : 6)//   - the maximal length of arrays (default : 50)// You can also pass an "options" object.// examples ://   var json = JSON.prune(window)//   var arr = Array.apply(0,Array(1000)); var json = JSON.prune(arr, 4, 20)//   var json = JSON.prune(window.location, {inheritedProperties:true})// Web site : http://dystroy.org/JSON.prune/// JSON.prune on github : https://github.com/Canop/JSON.prune// This was discussed here : https://stackoverflow.com/q/13861254/263525// The code is based on Douglas Crockford's code : https://github.com/douglascrockford/JSON-js/blob/master/json2.js// No effort was done to support old browsers. JSON.prune will fail on IE8.
(function () {
    'use strict';

    varDEFAULT_MAX_DEPTH = 6;
    varDEFAULT_ARRAY_MAX_LENGTH = 50;
    var seen; // Same variable used for all stringificationsvar iterator; // either forEachEnumerableOwnProperty, forEachEnumerableProperty or forEachProperty// iterates on enumerable own properties (default behavior)var forEachEnumerableOwnProperty = function(obj, callback) {
        for (var k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) callback(k);
        }
    };
    // iterates on enumerable propertiesvar forEachEnumerableProperty = function(obj, callback) {
        for (var k in obj) callback(k);
    };
    // iterates on properties, even non enumerable and inherited ones// This is dangerousvar forEachProperty = function(obj, callback, excluded) {
        if (obj==null) return;
        excluded = excluded || {};
        Object.getOwnPropertyNames(obj).forEach(function(k){
            if (!excluded[k]) {
                callback(k);
                excluded[k] = true;
            }
        });
        forEachProperty(Object.getPrototypeOf(obj), callback, excluded);
    };

    Date.prototype.toPrunedJSON = Date.prototype.toJSON;
    String.prototype.toPrunedJSON = String.prototype.toJSON;

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        meta = {    // table of character substitutions'\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };

    functionquote(string) {
        escapable.lastIndex = 0;
        return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
            var c = meta[a];
            returntypeof c === 'string'
                ? c
                : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
        }) + '"' : '"' + string + '"';
    }

    functionstr(key, holder, depthDecr, arrayMaxLength) {
        var i, k, v, length, partial, value = holder[key];
        if (value && typeof value === 'object' && typeof value.toPrunedJSON === 'function') {
            value = value.toPrunedJSON(key);
        }

        switch (typeof value) {
        case'string':
            returnquote(value);
        case'number':
            returnisFinite(value) ? String(value) : 'null';
        case'boolean':
        case'null':
            returnString(value);
        case'object':
            if (!value) {
                return'null';
            }
            if (depthDecr<=0 || seen.indexOf(value)!==-1) {
                return'"-pruned-"';
            }
            seen.push(value);
            partial = [];
            if (Object.prototype.toString.apply(value) === '[object Array]') {
                length = Math.min(value.length, arrayMaxLength);
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value, depthDecr-1, arrayMaxLength) || 'null';
                }
                return'[' + partial.join(',') + ']';
            }
            iterator(value, function(k) {
                try {
                    v = str(k, value, depthDecr-1, arrayMaxLength);
                    if (v) partial.push(quote(k) + ':' + v);
                } catch (e) { 
                    // this try/catch due to forbidden accessors on some objects
                }               
            });
            return'{' + partial.join(',') + '}';
        }
    }

    JSON.prune = function (value, depthDecr, arrayMaxLength) {
        if (typeof depthDecr == "object") {
            var options = depthDecr;
            depthDecr = options.depthDecr;
            arrayMaxLength = options.arrayMaxLength;
            iterator = options.iterator || forEachEnumerableOwnProperty;
            if (options.allProperties) iterator = forEachProperty;
            elseif (options.inheritedProperties) iterator = forEachEnumerableProperty
        } else {
            iterator = forEachEnumerableOwnProperty;
        }
        seen = [];
        depthDecr = depthDecr || DEFAULT_MAX_DEPTH;
        arrayMaxLength = arrayMaxLength || DEFAULT_ARRAY_MAX_LENGTH;
        returnstr('', {'': value}, depthDecr, arrayMaxLength);
    };

    JSON.prune.log = function() {
        console.log.apply(console,  Array.prototype.slice.call(arguments).map(function(v){returnJSON.parse(JSON.prune(v))}));
    }
    JSON.prune.forEachProperty = forEachProperty; // you might want to also assign it to Object.forEachProperty

}());

Solution 4:

You don't get an error? I get TypeError: Converting circular structure to JSON. I would say, it cannot be done.

Also, window and window.self point to the same object (the Global object), so you don't need to use that property...

Solution 5:

In Chrome 8 dev, I get TypeError: Converting circular structure to JSON (window generally contains a self-referential self, window, and top reference, if you're not in a frame), so directly using JSON.stringify will not work.

It sounds like you're using this for debug output. If you care only about some information, you could copy that information to an object, and then stringify it. Then encapsulate it in a function to grab all the information that you think you'll ever care about from window.

var data = JSON.stringify({
    'location': window.location// etc
});

Post a Comment for "Stringify Domwindow Object"