Developer Runs locally Ready to use Built-in examples No tracking

URL Parser

Paste a full URL to split it into scheme, credentials, hostname, port, path, query string and fragment; query parameters are listed with decoded values and the origin follows the browser same-origin convention.

Working out what a URL actually says comes up constantly: a blank page after a redirect means checking whether the query parameters arrived, a mismatched analytics event means checking whether a parameter name was misspelled, a CORS error means checking what the origin really is. This tool splits a URL into its standard parts — scheme, credentials, hostname, port, path, query string and fragment — one per line, with empty parts shown explicitly rather than left to be counted by eye.

Query parameters are listed separately in a table, each name beside its decoded value, so percent-encoded bytes appear as the characters they stand for and a plus sign is decoded as a space per the form convention; a parameter that fails to decode keeps its raw text while the rest continue to parse. The origin follows the standard construction — a default port, 80 for http and 443 for https, does not appear in it — matching how the browser's same-origin policy decides.

How to use

  1. Paste the full URL.
  2. Read each component on its own line.
  3. Check the query parameter table with decoded values.
  4. Compare the origin with how the browser computes it.

How it works

The standard URL structure

A URL's canonical shape is scheme://user:password@host:port/path?query#fragment. The tool takes it apart field by field: grab the scheme, strip the fragment (after #) and the query (after ?), then find the host in what remains — with a // prefix, everything before @ is user info and the host ends at the first /. Each field prints on its own line, with empty ones marked (none) explicitly — no eyeballing symbols.

Host, port and origin rules

Host and port split by standard rules: for regular domains look at the last colon (pure digits after it mean a port); IPv6 literals carry colons inside brackets, so the port parses after ]. Origin follows the browser same-origin-policy definition: http's default 80 and https's 443 are omitted, other ports (8080, 3000) show as-is — this line is authoritative for cross-origin debugging.

How query parameters decode

Query parameters separate on & and join keys to values with =; each is decoded and listed: percent-encoding (%E4%BD%A0%E5%A5%BD → 你好) restores via UTF-8, and + decodes to space per form convention. A segment that fails to decode keeps its original text while the rest continue parsing. Fragments never reach the server — when debugging API inputs, read the query string, not the fragment.

Code example

JavaScript The URL API parses everything at once

// browsers and Node both ship URL: protocol, host, path and query come out structured
const u = new URL('https://user:pass@example.com:8443/a/b?x=1&y=%E4%B8%AD#frag');

u.protocol;        // 'https:'
u.hostname;        // 'example.com'
u.port;            // '8443'
u.pathname;        // '/a/b'
u.search;          // '?x=1&y=%E4%B8%AD'
u.hash;            // '#frag'
u.username;        // 'user'

// read query params through searchParams: percent-encoding is decoded for you
u.searchParams.get('y');                        // decoded %E4%B8%AD
[...u.searchParams].map(([k, v]) => k + '=' + v);  // ['x=1', 'y=<decoded>']

// only want the decoded path segment (protocol irrelevant)? use a relative base
new URL('/a%20b/c', 'https://example.com').pathname;   // '/a%20b/c'
decodeURIComponent('/a%20b');                          // '/a b'

Python Taking URLs apart with urllib.parse

from urllib.parse import urlparse, parse_qs, urlencode, urlunparse

u = urlparse('https://user:pass@example.com:8443/a/b?x=1&y=%E4%B8%AD#frag')
print(u.scheme, u.netloc, u.path)          # https user:pass@example.com:8443 /a/b
print(u.hostname, u.port)                  # example.com 8443
print(parse_qs(u.query))                   # {'x': ['1'], 'y': ['\u4e2d' as text]}

# rebuilding: replace the parts, then urlunparse (encode the query yourself)
q = urlencode({'x': '1', 'y': 'text'})
print(urlunparse(u._replace(query=q, fragment='')))

FAQ

Why does the URL need a scheme to parse?

The scheme fixes the default port (http 80, https 443, ftp 21) and the origin's construction; without it, example.com can't be reliably told apart as a host or a path. Add http:// or https:// and it parses.

What's special about ports 80 and 443?

They're http and https defaults, omitted by browsers in the address bar and absent from origin — http://a.com:80 and http://a.com are the same origin. Other ports (8080, 3000) display explicitly.

Are Chinese values in parameters decoded?

Yes. %E4%BD%A0%E5%A5%BD decodes to the Chinese greeting, and + becomes a space by form convention; sequences violating percent-encoding keep their original text while later parameters still parse — no all-or-nothing failure.

Is the fragment (after #) sent to the server?

No. The fragment stays in the browser for in-page navigation and is stripped before the request is sent. When checking API inputs, look at the query string, never the fragment.

What does user:pass@ mean?

The URL standard allows credentials before the host (modern browsers are phasing it out). The tool separates the username and password — and seeing @ in an unfamiliar URL is a phishing warning: the real host comes after the @.

Are internationalized domains (xn--...) converted?

No. URLs that browsers send already carry punycode (xn-- prefix); the hostname displays as-is with no punycode-to-Chinese conversion, so you always see the actual wire value.

Can URLs with leading/trailing spaces or newlines parse?

Leading and trailing whitespace is trimmed before parsing; newlines in the middle break the URL's structure — make sure you paste one complete single-line address.