obj2query -- turn a Javascript Object into a Query String

When dealing with XHR, you often need to pass Javascript data to your server side script in a serialised form. This snippet (taken from jif.js) takes a Javascript object and serializes it into a query string, suitable for passing via a GET or POST request.

It takes one, two or three arguments:

obj
A javascript object. If you give it anything that isn't an object (like a string or number) then the result will be an empty string.
forPHP -- optional
This optional parameter decides if arrays should expand to foo[] rather than the more normal foo. If you leave this argument off, then it will be guessed based on the current page's location ending with .php.
parentObject -- optional
The parentObject is prepended to all name parts of the query string, followed by a period (.). For example, if the parentObject is 'foo', then {a:12} will result in foo.a=12. (Note: if you wish to provide a parentObject, you'll need to specify the forPHP parameter explicitly and override the guessing).

function obj2query(obj, forPHP, parentObject){
   if( typeof obj != 'object' ) return '';

   if (arguments.length == 1)
      forPHP = /\.php$/.test(document.location.href);
   
   var rv = '';
   for(var prop in obj) if (obj.hasOwnProperty(prop) ) {

      var qname = parentObject
         ? parentObject + '.' + prop
         : prop;

      // Expand Arrays
      if (obj[prop] instanceof Array)
         for( var i = 0; i < obj[prop].length; i++ )
            if( typeof obj[prop][i] == 'object' )
               rv += '&' + obj2query( obj[prop][i], forPHP, qname );
            else
               rv += '&' + encodeURIComponent(qname) + (forPHP ? '[]' : '')
					+ '=' + encodeURIComponent( obj[prop][i] );

      // Expand Dates
      else if (obj[prop] instanceof Date)
         rv += '&' + encodeURIComponent(qname) + '=' + obj[prop].getTime();

      // Expand Objects
      else if (obj[prop] instanceof Object)
         // If they're String() or Number() etc
         if (obj.toString && obj.toString !== Object.prototype.toString)
            rv += '&' + encodeURIComponent(qname) + '=' + encodeURIComponent( obj[prop].toString() );
         // Otherwise, we want the raw properties
         else
            rv += '&' + obj2query(obj[prop], forPHP, qname);

      // Output non-object
      else
         rv += '&' + encodeURIComponent(qname) + '=' + encodeURIComponent( obj[prop] );

   }
   return rv.replace(/^&/,'');
}

Try it!

Enter a JSON object:

2008-03-24: Taken from jif.js 2008-03-24: Changes after discussion with Twey in ##javascript