Query string
The query string is the part of a URL after the "?" and before any "#", made of key=value pairs joined by "&", used to pass parameters to a page or API. Its format is a convention layered on top of the URL standard, not one strict specification.
Anatomy of a URL
https://shop.example.com:8443/search/wine?q=caf%C3%A9&tag=a&tag=b#results
\___/ \_______________/\___/\_________/ \____________________/ \_____/
scheme host port path query fragment
The query starts at the first ? and ends at the first #. The fragment after it is handled by the browser and is never sent to the server, so a ? that appears inside the fragment is not part of the query.
Pairs, keys and values
By convention the query is a list of key=value pairs separated by &. Each key and value is percent-encoded, and a + usually stands for a space. Several details vary:
- Repeated keys.
tag=a&tag=bis common. Some frameworks read it as a list, and some keep only the first or last value. - Array syntax. Conventions like
a[]=1&a[]=2ora[0]=1are interpreted by the server framework, not by the URL standard. - Bare flags and empty values.
?debugand?debug=are different strings, and libraries disagree on whether they mean the same thing. - Order. Pairs keep their order, and some signing schemes depend on it.
- Separators. Older specifications also allowed
;instead of&. Modern parsers generally do not.
Reading and building one
In JavaScript, new URL(text).searchParams reads a query and searchParams.set('q', value) writes one, encoding correctly as it goes. In Python, urllib.parse.parse_qs and urlencode do the same. Building a query by string concatenation is where most encoding bugs come from.
Common pitfalls
- Putting secrets in the query. Query strings appear in server logs, browser history and
Refererheaders. Tokens and passwords belong in headers or request bodies. - Unencoded values. A value containing
&,=or#that is not encoded splits or truncates the query. - Length limits. Servers, proxies and browsers impose limits on URL length, so very large payloads belong in a request body.
- Trusting parameter names and types. Every value arrives as a string, and the same key may arrive several times.
Related terms
- Percent-encoding — Percent-encoding, also called URL encoding, writes a character as a percent sign followed by the hexadecimal value of each of its UTF-8 bytes, such as %20 for a space, so text can be carried safely inside a URL. It is defined in RFC 3986.
- Base64URL — Base64URL is a variant of Base64 that swaps the characters "+" and "/" for "-" and "_" and usually drops the "=" padding, so encoded bytes can sit safely inside URLs, filenames and JWTs. It is defined in RFC 4648, section 5.
References
Ads on this page
Non-personalized ads help keep Vaultools free — Google decides where they appear on the page.
Go Pro to remove them →