Base64vs URL EncodingUpdated May 2026 · 5 min read

Base64 vs URL Encoding

Both convert data into a safe-to-transmit format — but they solve completely different problems. Mixing them up is one of the most common sources of subtle encoding bugs in web development.

TL;DR

  • Base64: converts binary data (images, files, keys) to printable ASCII. Output is 33% larger. Not URL-safe by default — use Base64URL for URLs.
  • URL encoding (percent-encoding): makes arbitrary text safe in URLs by replacing special characters with %HH hex codes. Use encodeURIComponent() for query params.
  • Base64 is not encryption — it's trivially reversible with no key. Never use it to hide sensitive data.
  • Common mistake: embedding a Base64 string (containing +, /, =) directly in a URL without Base64URL conversion or percent-encoding.

At a Glance

AttributeBase64URL Encoding (Percent-Encoding)
PurposeEncode binary data as printable ASCII textMake arbitrary text safe inside URLs
StandardRFC 4648RFC 3986
Character setA-Z, a-z, 0-9, +, /, = (64 + padding)Unreserved chars only; others as %HH
Example outputSGVsbG8gV29ybGQ=Hello%20World%21
Output size~133% of input (33% overhead)Varies — ASCII text often unchanged
URL-safe variantBase64URL: + → -, / → _, drop =This IS the URL-safe encoding
Reversible?Yes — trivially, no key neededYes — trivially, use decodeURIComponent()
Encrypts data?No — encoding onlyNo — encoding only
Use in query stringsOnly with Base64URL or after percent-encodingDesigned for this — encode values only
Binary data supportYes — primary use caseLimited — text focused
Common inJWTs, data URIs, email attachments, PEM keysURL query params, form submissions, path segments

Encoding Examples

InputBase64URL Encoded
Hello WorldSGVsbG8gV29ybGQ=Hello%20World
user@example.comdXNlckBleGFtcGxlLmNvbQ==user%40example.com
price=100&tax=5cHJpY2U9MTAwJnRheD01price%3D100%26tax%3D5
https://x.com/pathaHR0cHM6Ly94LmNvbS9wYXRohttps%3A%2F%2Fx.com%2Fpath
name: JoãobmFtZTogSm/Do28=name%3A%20Jo%C3%A3o
<script>alert(1)</script>PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==%3Cscript%3Ealert(1)%3C%2Fscript%3E

Quick Decision

Use Base64 when…

  • Embedding images in HTML (data:image/png;base64,...)
  • Encoding binary file attachments in email (MIME)
  • Storing binary data in JSON or XML payloads
  • Encoding cryptographic keys (PEM format)
  • Transmitting binary data through text-only channels
  • JWT tokens (uses Base64URL variant)

Use URL Encoding when…

  • Embedding user input in URL query parameters
  • Constructing URLs with special characters (spaces, &, =)
  • Form submissions with application/x-www-form-urlencoded
  • Encoding path segments in REST API URLs
  • Building search query strings with arbitrary user text
  • Encoding redirect URLs passed as query parameters

Real-World Patterns

The JWT URL Embedding Bug

A developer passes a JWT as a query parameter: /callback?token=eyJhbGc...+abc/xyz=. Standard Base64 uses + and /, which have special meaning in URLs. The + is decoded as a space; the / may be treated as a path separator. The server receives a corrupted token and authentication fails. The fix: JWTs use Base64URL (not standard Base64) — they replace + with -, / with _, and drop = padding. Always use a JWT library rather than manual Base64 encoding to avoid this class of bug.

Passing URLs as Query Parameters

A redirect parameter in a login flow: /login?redirect=https://app.com/dashboard?tab=settings&user=42. Without encoding, the outer URL parser sees & as a parameter separator and reads redirect=https://app.com/dashboard?tab=settings and then user=42 as a separate parameter. The correct construction: encodeURIComponent('https://app.com/dashboard?tab=settings&user=42') → 'https%3A%2F%2Fapp.com%2Fdashboard%3Ftab%3Dsettings%26user%3D42'. Then the outer URL sees it as a single opaque value.

Data URIs with Base64

An inline SVG or image in HTML: <img src="data:image/png;base64,iVBORw0KGgo...">. The browser decodes the Base64 string and renders the image without any HTTP request — useful for small icons in components or email HTML where external URL references may be blocked. The overhead: Base64 increases file size by 33%, and inline data URIs aren't cached separately from the HTML. Best for small images (under 2–5KB); for larger images, external URLs with proper caching are more efficient.

API Basic Authentication Header

HTTP Basic Authentication sends credentials as: Authorization: Basic Base64(username:password). The colon-separated username:password string is Base64-encoded and sent in every request header. This is not secure without HTTPS — Base64 is trivially decoded by anyone intercepting the traffic. With HTTPS, it's acceptable for simple server-to-server API auth. The encoding in Python: import base64; base64.b64encode(b'user:pass').decode(). The common mistake: thinking the Base64 makes the credentials secure — it does not. Always use HTTPS.

Verdict: Different Tools for Different Problems

Base64 and URL encoding solve completely different problems. Base64 makes binary data transmittable as text. URL encoding makes arbitrary text safe inside URLs. Using Base64 where you need URL encoding (embedding raw Base64 in a URL) breaks URLs. Using URL encoding where you need Base64 (encoding binary data as %XX sequences) is inefficient and wrong.

Remember: if you're putting data in a URL query string, use encodeURIComponent(). If you're encoding binary data for a text channel, use Base64. If you're doing both (putting Base64 in a URL), use Base64URL — the variant designed specifically for URL contexts.

Decision Checklist

ScenarioUse
Embedding image in HTML without external requestBase64
User input in URL query parameterURL Encoding
Sending JWT in URL or query stringBase64URL
HTTP Basic Auth header credentialsBase64
Encoding redirect URL as a query paramURL Encoding
PEM-encoded certificate or private keyBase64
Constructing a search query with special charsURL Encoding
Email attachment (MIME multipart)Base64
Path segment with slashes or special charsURL Encoding
Binary file in JSON payloadBase64
OAuth2 state or code_verifier in URLURL Encoding (or Base64URL)
Hiding sensitive data from casual inspectionNeither — use encryption

Frequently Asked Questions

Why is Base64 not URL-safe?

Standard Base64 uses three characters that have special meaning in URLs: + (represents a space in query strings), / (path separator), and = (key=value separator). If you put a standard Base64 string in a URL query parameter, + will be decoded as a space, / may be interpreted as a path separator, and = may confuse parameter parsers. The solution is Base64URL (RFC 4648 §5): replace + with -, replace / with _, and omit padding =. JWT tokens use Base64URL for exactly this reason — they are frequently embedded in URLs and Authorization headers.

What is percent-encoding (URL encoding)?

Percent-encoding (RFC 3986) replaces characters that have special meaning in URLs with a % followed by the character's hexadecimal ASCII code. A space becomes %20, & becomes %26, = becomes %3D, + becomes %2B. Only unreserved characters (A-Z, a-z, 0-9, -, _, ., ~) can appear in URLs unencoded. Everything else must be percent-encoded. Most languages provide built-in functions: JavaScript encodeURIComponent(), Python urllib.parse.quote(), Java URLEncoder.encode().

What does Base64 actually do?

Base64 converts arbitrary binary data into a string using only 64 printable ASCII characters (A-Z, a-z, 0-9, +, /). It groups input bytes in sets of 3 (24 bits) and converts each group into 4 Base64 characters (6 bits each). This produces output 33% larger than the input — 3 bytes become 4 characters. It is used primarily to transmit binary data over text-based channels: embedding images in HTML (data URIs), sending files in email (MIME), storing binary data in JSON payloads, and encoding cryptographic keys and certificates in PEM format.

Is Base64 a form of encryption?

No — Base64 is encoding, not encryption. It is trivially reversible by anyone without any key or secret. Decoding a Base64 string requires no authentication, no key, no secret. Base64 provides zero confidentiality. It is purely a representation format — a way to represent binary data as ASCII text. Never use Base64 to 'hide' sensitive data. This is a common beginner mistake: hardcoding an API key as Base64 in client-side JavaScript provides no security — any user who inspects network requests or the source code can instantly decode it.

When should I use encodeURI vs encodeURIComponent in JavaScript?

encodeURIComponent() encodes everything except unreserved characters (A-Z, a-z, 0-9, -, _, ., ~, !, *, ', (, )). Use it for encoding individual query parameter values or path segments. encodeURI() does not encode characters that are valid in a complete URI (/, ?, #, &, =, :, @, etc.) — it encodes a full URL without breaking its structure. The correct usage: build the full URL with encodeURIComponent() for each parameter value, then treat the assembled URL as a unit. Never use encodeURI() for query parameter values — it will leave = and & unencoded, breaking the query string.

What is the difference between application/x-www-form-urlencoded and percent-encoding?

application/x-www-form-urlencoded is a specific encoding for HTML form submissions that uses percent-encoding with one important difference: spaces are encoded as + rather than %20. This is a legacy convention from early web forms. Pure RFC 3986 percent-encoding always uses %20 for spaces. Confusing the two causes bugs: if your backend expects form-urlencoded (spaces as +) but receives %20 from a non-form client (or vice versa), space characters will be mishandled. Always use %20 in URL query strings; + is only unambiguous in form-urlencoded bodies.

Can Base64 encode any data? What about Unicode?

Base64 encodes bytes — arbitrary binary data — not text directly. For Unicode text, you must first encode the text to bytes (usually UTF-8), then Base64-encode the bytes. btoa() in browsers only handles Latin-1 characters and will throw on multi-byte Unicode. The correct approach: new TextEncoder().encode(string) → Uint8Array → Base64. atob() has the same limitation on decode. Many developers hit this bug when trying to Base64-encode strings containing emoji, Chinese characters, or diacritics. Always ensure UTF-8 encoding before Base64.

What is double URL encoding and when is it a problem?

Double URL encoding happens when a percent-encoded string is encoded again: a space → %20 → %2520 (% itself encoded as %25). This occurs when developers accidentally encode an already-encoded value, or when frameworks auto-encode values that were manually encoded. It is also a known security issue: some web application firewalls and input validators check for %20 (space) as a SQL injection or path traversal pattern, but miss %2520 (double-encoded space). Always decode exactly once at the appropriate layer. If you receive a URL from another system, check whether it's already encoded before re-encoding.

Related Comparisons

Verdict: Choose Based On Your Situation

Base64

  • You need to transmit binary data as text
  • You're embedding data in JSON, XML, or HTML attributes
  • You need reversible encoding of any data type
  • You're using data URIs for inline images

URL Encoding

  • You're encoding query parameters or form data
  • You need compact encoding of text with special characters
  • You're building API request URLs
  • You want human-readable output

Related Tools