开发者

Serialize JavaScript's navigator object

I'm creating a page to help diagnose the problem our users are experiencing with our web pages (you know, asking a user "What browser are you using?" usually leads to "Internet").

This page already submits to me all the HTTP headers and now I'm trying to have JavaScript give some more informations, so I thought it would be great to have the user's navigator JavaScript object and I started looking how to serialize it so I can submit it through a form.

The problem is I'm not able to serialize the navigator object using any JSON library I know of, everyone returns an empty object (?!), so I decided to write an ad-hoc serializer.

You can find the code here:

<!DOCTYPE html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            function serialize (object) {
                var type = typeof object;
                if (object === null) {
                    return '"nullValue"';
                }
                if (type == 'string' || type === 'number' || type === 'boolean') {
 开发者_Go百科                   return '"' + object + '"';
                }
                else if (type === 'function') {
                    return '"functionValue"';
                }
                else if (type === 'object') {
                    var output = '{';
                    for (var item in object) {
                        if (item !== 'enabledPlugin') {
                            output += '"' + item + '":' + serialize(object[item]) + ',';
                        }
                    }
                    return output.replace(/\,$/, '') + '}';
                }
                else if (type === 'undefined') {
                    return '"undefinedError"';
                }
                else {
                    return '"unknownTypeError"';
                }
            };
            $(document).ready(function () {
                $('#navigator').text(serialize(navigator));
            });
        </script>
        <style type="text/css">
            #navigator {
                font-family: monospaced;
            }
        </style>
        <title>Serialize</title>
    </head>
    <body>
        <h1>Serialize</h1>
        <p id="navigator"></p>
    </body>
</html>

This code seems to work perfectly in Firefox, Opera, Chrome and Safari but (obviously) doesn't work in Internet Explorer (at least version 8.0), it complains that "Property or method not supported by the object" at line for (var item in object) {.

Do you have any hint on how to fix the code or how to reach the goal (serialize the navigator object) by other means?


Solution (v 2.0):

Replace

for (var item in object) {
    if (item !== 'enabledPlugin') {
        output += '"' + item + '":' + serialize(object[item]) + ',';
    }
}

with

for (var item in object) {
    try {
        if (item !== 'enabledPlugin') {
            output += '"' + item + '":' + serialize(object[item]) + ',';
        }
    }
    catch (e) {
    }
}

and it works.


Try putting it inside a new object

var _navigator = {};
for (var i in navigator) _navigator[i] = navigator[i];

And then serialize it (maybe using some JSON library if the browser doesn't have native JSON API, I use json2.js):

$('#navigator').text(JSON.stringify(_navigator));

Edit: It seems that Internet Explorer doesn't allow navigator.plugins and navigator.mimeTypes to be iterated over, so this works:

var _navigator = {};
for (var i in navigator) _navigator[i] = navigator[i];

delete _navigator.plugins;
delete _navigator.mimeTypes;

$('#navigator').text(JSON.stringify(_navigator));


JSON in accepted answer contains only top level elements. Check this out https://jsfiddle.net/j1zb7qm0/ - _navigator.connection is empty. I've wrote a small func to collect all nested properties:

function recur(obj) {
  var result = {}, _tmp;
  for (var i in obj) {
    // enabledPlugin is too nested, also skip functions
    if (i === 'enabledPlugin' || typeof obj[i] === 'function') {
        continue;
    } else if (typeof obj[i] === 'object') {
        // get props recursively
        _tmp = recur(obj[i]);
        // if object is not {}
        if (Object.keys(_tmp).length) {
            result[i] = _tmp;
        }
    } else {
        // string, number or boolean
        result[i] = obj[i];
    }
  }
  return result;
}

You can use it like this var _navigator = recur(navigator) or create your own wrapper. In fact you can use it to iterate over and copy any nested object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜