[javascript] How can I get query string values in JavaScript?

Doing this reliably is more involved than one may think at first.

  1. location.search, which is used in other answers, is brittle and should be avoided - for example, it returns empty if someone screws up and puts a #fragment identifier before the ?query string.
  2. There are a number of ways URLs get automatically escaped in the browser, which makes decodeURIComponent pretty much mandatory, in my opinion.
  3. Many query strings are generated from user input, which means assumptions about the URL content are very bad. Including very basic things like that each key is unique or even has a value.

To solve this, here is a configurable API with a healthy dose of defensive programming. Note that it can be made half the size if you are willing to hardcode some of the variables, or if the input can never include hasOwnProperty, etc.

Version 1: Returns a data object with names and values for each parameter. It effectively de-duplicates them and always respects the first one found from left-to-right.

function getQueryData(url, paramKey, pairKey, missingValue, decode) {

    var query, queryStart, fragStart, pairKeyStart, i, len, name, value, result;

    if (!url || typeof url !== 'string') {
        url = location.href; // more robust than location.search, which is flaky
    }
    if (!paramKey || typeof paramKey !== 'string') {
        paramKey = '&';
    }
    if (!pairKey || typeof pairKey !== 'string') {
        pairKey = '=';
    }
    // when you do not explicitly tell the API...
    if (arguments.length < 5) {
        // it will unescape parameter keys and values by default...
        decode = true;
    }

    queryStart = url.indexOf('?');
    if (queryStart >= 0) {
        // grab everything after the very first ? question mark...
        query = url.substring(queryStart + 1);
    } else {
        // assume the input is already parameter data...
        query = url;
    }
    // remove fragment identifiers...
    fragStart = query.indexOf('#');
    if (fragStart >= 0) {
        // remove everything after the first # hash mark...
        query = query.substring(0, fragStart);
    }
    // make sure at this point we have enough material to do something useful...
    if (query.indexOf(paramKey) >= 0 || query.indexOf(pairKey) >= 0) {
        // we no longer need the whole query, so get the parameters...
        query = query.split(paramKey);
        result = {};
        // loop through the parameters...
        for (i = 0, len = query.length; i < len; i = i + 1) {
            pairKeyStart = query[i].indexOf(pairKey);
            if (pairKeyStart >= 0) {
                name = query[i].substring(0, pairKeyStart);
            } else {
                name = query[i];
            }
            // only continue for non-empty names that we have not seen before...
            if (name && !Object.prototype.hasOwnProperty.call(result, name)) {
                if (decode) {
                    // unescape characters with special meaning like ? and #
                    name = decodeURIComponent(name);
                }
                if (pairKeyStart >= 0) {
                    value = query[i].substring(pairKeyStart + 1);
                    if (value) {
                        if (decode) {
                            value = decodeURIComponent(value);
                        }
                    } else {
                        value = missingValue;
                    }
                } else {
                    value = missingValue;
                }
                result[name] = value;
            }
        }
        return result;
    }
}

Version 2: Returns a data map object with two identical length arrays, one for names and one for values, with an index for each parameter. This one supports duplicate names and intentionally does not de-duplicate them, because that is probably why you would want to use this format.

function getQueryData(url, paramKey, pairKey, missingValue, decode) {

    var query, queryStart, fragStart, pairKeyStart, i, len, name, value, result;

    if (!url || typeof url !== 'string') {
          url = location.href; // more robust than location.search, which is flaky
    }
        if (!paramKey || typeof paramKey !== 'string') {
            paramKey = '&';
        }
        if (!pairKey || typeof pairKey !== 'string') {
            pairKey = '=';
        }
        // when you do not explicitly tell the API...
        if (arguments.length < 5) {
            // it will unescape parameter keys and values by default...
            decode = true;
        }

        queryStart = url.indexOf('?');
        if (queryStart >= 0) {
            // grab everything after the very first ? question mark...
            query = url.substring(queryStart + 1);
        } else {
            // assume the input is already parameter data...
            query = url;
        }
        // remove fragment identifiers...
        fragStart = query.indexOf('#');
        if (fragStart >= 0) {
            // remove everything after the first # hash mark...
            query = query.substring(0, fragStart);
        }
        // make sure at this point we have enough material to do something useful...
        if (query.indexOf(paramKey) >= 0 || query.indexOf(pairKey) >= 0) {
            // we no longer need the whole query, so get the parameters...
            query = query.split(paramKey);
            result = {
                names: [],
                values: []
            };
            // loop through the parameters...
            for (i = 0, len = query.length; i < len; i = i + 1) {
                pairKeyStart = query[i].indexOf(pairKey);
                if (pairKeyStart >= 0) {
                    name = query[i].substring(0, pairKeyStart);
                } else {
                    name = query[i];
                }
                // only continue for non-empty names...
                if (name) {
                    if (decode) {
                        // unescape characters with special meaning like ? and #
                        name = decodeURIComponent(name);
                    }
                    if (pairKeyStart >= 0) {
                        value = query[i].substring(pairKeyStart + 1);
                        if (value) {
                            if (decode) {
                                value = decodeURIComponent(value);
                            }
                        } else {
                            value = missingValue;
                        }
                    } else {
                        value = missingValue;
                    }
                    result.names.push(name);
                    result.values.push(value);
                }
           }
           return result;
       }
   }

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to url

What is the difference between URL parameters and query strings? Allow Access-Control-Allow-Origin header using HTML5 fetch API File URL "Not allowed to load local resource" in the Internet Browser Slack URL to open a channel from browser Getting absolute URLs using ASP.NET Core How do I load an HTTP URL with App Transport Security enabled in iOS 9? Adding form action in html in laravel React-router urls don't work when refreshing or writing manually URL for public Amazon S3 bucket How can I append a query parameter to an existing URL?

Examples related to plugins

How to view Plugin Manager in Notepad++ How to install a Notepad++ plugin offline? "Gradle Version 2.10 is required." Error How to download PDF automatically using js? How to: Install Plugin in Android Studio "application blocked by security settings" prevent applets running using oracle SE 7 update 51 on firefox on Linux mint How can I call a WordPress shortcode within a template? How can I simulate mobile devices and debug in Firefox Browser? How to install plugins to Sublime Text 2 editor? How to add java plugin for Firefox on Linux?

Examples related to query-string

How can I get (query string) parameters from the URL in Next.js? How to read values from the querystring with ASP.NET Core? What is the difference between URL parameters and query strings? How to get URL parameter using jQuery or plain JavaScript? How to access the GET parameters after "?" in Express? node.js http 'get' request with query string parameters Escaping ampersand in URL In Go's http package, how do I get the query string on a POST request? Append values to query string Node.js: Difference between req.query[] and req.params