Simulating PHP $_GET in JavaScript (with multiple dimensions)

Idea

JavaScript does not provide a built-in way to access the variables passed into the URL of a page (the query string).

However it is possible to use the standard window.location object to retrieve these variables and their associated values.

window.location.search contains the query string (and the additional ‘?’ at the start). We can process it and store our results into a multidimensional array, as the following scripts demonstrate:

The script

var $_GET = (function() {
// Split the params part of the URL into "key=value" pairs
   var pairs = window.location.search.slice(1).split("&");
   var params = [];

// Split each pair and store their values into the params array
   for(i in pairs) {
      var splitPairs = pairs[i].split("=");
      var name = unescape(splitPairs[0]);
      var value = unescape(splitPairs[1]);

// Check for valid name
      var match = name.match(/^(\w+)(?:\[\w*\])*$/);
      if( !match ) continue;

      var dimensions = [match[1]];
      var sub = match[0];
      var re = /\[(\w*)\]/g;

      while( match = re.exec(sub) ) {
         var dim = match[1];

         if(dim == "") {
            dim = null;
         } else if( dim == parseInt(dim)) {
            dim = parseInt(dim);
         }

         dimensions.push(dim);
      }

// Build params array with multiple dimensions
      (function(p, d) {

         var s = d.shift()

         if( s === null ) {
            s = -1;

            for(var i in p) {
               if(i > s) {
                   s = i;
               }
            }
            ++s;
         }

         if( d.length ) {
            p[s] = p[s] || [];
            arguments.callee(p[s], d);
         } else {
            p[s] = value;
         }
      })(params, dimensions);
   }
   return params;
})();

This script creates a $_GET array containing variables passed to the page via URL parameters, like in PHP.
It will also work when multi-dimensional variables appear.

Why so complicated?

This script is can deal with the case of multi-dimensional arrays with or without keys.
It also reproduces the behaviour of the array type in PHP.

If a key is not specified for a value, the maximum of the integer indices is taken and the new key will be that value plus 1. If a key that already has an assigned value is specified, that value will be overwritten.

This means if we use the following URL:

http://www.example.com?person[3]=John&person[]=Peter&person[]=Jack

The $_GET variable will be:

PHP JavaScript
Array
(
   [person] =>; Array
   (
      [3] => John
      [4] => Peter
      [5] => Jack
   )
)
[
   person: [
      undefined,
      undefined,
      undefined,
      "John",
      "Peter",
      "Jack"
   ]
]

Usage example

// If the page URL is www.example.com/page.html?user=John%20Smith
// this will display "Hello John Smith"
alert("Hello " + $_GET["user"]);

// If the URL is www.example.com/page.html?user[name]=John&user[surname]=Smith
alert("Hello " + $_GET["user"]["name"] + " " + $_GET["user"]["surname"]);

// If the URL is www.example.com/page.html?user[]=John&user[]=Peter
alert($_GET["user"][0]); // John
alert($_GET["user"][1]); // Peter

XSS injections?

Inevitably… If users can change parameters that affect the content of a page, this opens up the danger of XSS injections.

// www.example.com/page.html?name=John<script src="maliciousscript.js"></script>

if($_GET["name"] == "John") {
   doSomething(); // OK
}

document.write($_GET["name"]); // Ouch!

Principles that apply for server-side scripting also apply in this case: Do not display anything that comes directly from the query string. Always sanitise first.

JavaScript does not provide a function to strip HTML tags or replace special characters with their equivalent HTML code, so you will have to write your own if you need to display variables from the query string.

This entry was posted in JavaScript, PHP. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>