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.
精彩评论