Query String Builder

When a request turns up in a log with the wrong filter applied, the fastest way to find out why is to pull the query string apart and read what actually arrived. This does that in a table, decoding the percent sequences and flagging the things that are invisible in a raw string — a key that appears twice, a value that is empty rather than absent, an encoding that was cut in half. It also runs the other way, turning a list of pairs into a query string you can paste.

Query String Builder and Parser — Take Parameters Apart or Put Them TogetherBuildFigure

Where the question mark divides things

An address is three pieces: everything before the ? is the path, everything between the ? and the # is the query, and everything after the # is the fragment. The query is split on & into items, and each item is split at its first = into a key and a value. The word first matters: a Base64 value ending in = padding, or a filter expression containing an equals sign, keeps everything after the first one as part of the value. That is why a parameter carrying a token usually parses correctly even though it looks like it should not. The fragment is never transmitted, so if you are searching an access log for something that was after a #, it was never there to find.

Percent encoding, and the plus sign problem

Only a small set of characters can appear literally in a URL, so anything else is written as its bytes in hex: a space becomes %20, and a character outside ASCII becomes two, three or four sequences depending on its UTF-8 length. Spaces have a second representation because application/x-www-form-urlencoded, the format an HTML form submits, writes them as +. That is why the parse side has a switch for it. Leave it on for anything that came from a form or a search box. Turn it off when a value legitimately contains a plus — a phone number in E.164 form, a version string, an arithmetic expression — otherwise you will read +1 415 as a space. Building has the mirror of this problem, and the answer there is simply to leave encoding on: a real plus becomes %2B and survives either interpretation.

Repeated keys have no standard behaviour

size=10&size=12 is syntactically fine and semantically undefined. PHP keeps the last value unless you write size[], in which case it builds an array. Node's default parser and the Java servlet API collect repeats into a list. Some frameworks take the first and drop the rest. Rails uses [] for arrays and nested bracket notation for hashes. None of this is in a specification you can point at, which is why a form with a multi-select saves one value in production and all of them in staging when the two run different stacks. This tool flags repeats and recognises the common bracket notations, but the flag is a prompt to go and read the receiving code, not an answer.

An empty value is not the same as an absent key

page= means the key is present with an empty string. page with no equals sign means the key is present with no value at all. Leaving the key out entirely means something different again. Most server code collapses the first two into an empty string, but the distinction survives often enough to matter: APIs that treat a valueless key as a boolean flag read ?debug as true, and search backends routinely distinguish "no filter" from "filter set to nothing" and return different result counts for each. When you are building a URL to reset a set of filters, keeping the empty keys is usually what you want, because it says explicitly that the filter was considered and cleared. When you are building a link for a human to click, dropping them keeps the address short enough to survive being pasted into a chat window.

Questions people ask

I pasted an address and got no parameters at all.

A string with no ? in it is treated as a path, because that is the only safe reading. If you copied just the query string, it needs to contain an = or an & for the tool to recognise it as one — a bare word could equally be a path segment, and guessing wrong would be worse than asking. Paste either the full address or the part after the question mark.

The decoded values are garbled.

The URL was almost certainly encoded in something other than UTF-8. Old systems produced query strings in regional codepages, and their percent sequences decode to the wrong characters or fail outright under UTF-8 rules. The tool marks those as decode failures and leaves the raw value in the table, so you still have the original bytes to hand to whatever converter you need.

Should I leave encoding on when building?

Yes, unless you are deliberately pasting values that are already encoded. With it on, spaces, ampersands, equals signs, hashes and non-ASCII characters are all escaped so they stay inside their own parameter. With it off, any of those will be read as structure by the server and split your value in a way that is hard to spot afterwards, because the resulting URL is still perfectly valid — it just means something else.

Does anything I paste get sent anywhere?

No. Splitting and joining strings is all this does, and it all happens in the page. That makes it safe for URLs containing session tokens, though the result is displayed on screen in full, so the usual care applies if someone is watching.

Related