惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
爱范儿
爱范儿
GbyAI
GbyAI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
美团技术团队
Y
Y Combinator Blog
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
M
MIT News - Artificial intelligence
博客园 - Franky
V
Visual Studio Blog
I
InfoQ
V
V2EX
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
博客园 - 司徒正美
L
LangChain Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
5 URL Encoding Bugs That Silently Break Your App
Dmytro · 2026-05-27 · via DEV Community

Every web developer hits URL encoding bugs eventually. A redirect loop that only happens with certain usernames. A search feature that breaks when someone types C++. An API that returns garbage when the query contains emoji.

These bugs are annoying because they fail silently — the URL looks fine in the browser, but the server receives corrupted data.

Here are 5 encoding mistakes I've seen (and made) in production, and how to fix each one.

1. Using encodeURI when you need encodeURIComponent

This is the classic one. You're building a URL with user input:

// User searches for "node.js & deno"
const query = 'node.js & deno';

// WRONG — encodeURI preserves & and =
const bad = `https://api.example.com/search?q=${encodeURI(query)}`;
// "https://api.example.com/search?q=node.js%20&%20deno"
// Server sees: q = "node.js " and a second param " deno" = undefined

// RIGHT — encodeURIComponent encodes everything
const good = `https://api.example.com/search?q=${encodeURIComponent(query)}`;
// "https://api.example.com/search?q=node.js%20%26%20deno"

Enter fullscreen mode Exit fullscreen mode

encodeURI() is designed for complete URLs — it preserves :, /, ?, &, =, #. If you use it on a value that contains &, the server interprets it as a parameter separator.

Rule: encodeURIComponent() for values. encodeURI() basically never (use the URL API instead).

2. Double encoding

This one is insidious. You encode a value, store it, then encode it again when building the URL:

const filename = 'my report.pdf';
const encoded = encodeURIComponent(filename); // "my%20report.pdf"

// Later, somewhere else in the codebase...
const url = `https://cdn.example.com/files/${encodeURIComponent(encoded)}`;
// "https://cdn.example.com/files/my%2520report.pdf"
//                                    ^^^^ %25 is the encoded %

Enter fullscreen mode Exit fullscreen mode

The % in %20 gets encoded to %25, producing %2520. The server decodes it to %20 (a literal string), not a space.

Fix: Encode raw values exactly once. If you're not sure whether a string is already encoded, decode first:

const safeEncode = (str) => encodeURIComponent(decodeURIComponent(str));

Enter fullscreen mode Exit fullscreen mode

3. Forgetting that + and %20 are different

Two ways to encode a space. Two different standards.

Encoding Standard Where it works
%20 RFC 3986 (URI) Everywhere
+ HTML forms (application/x-www-form-urlencoded) Query strings only
// These produce different output
encodeURIComponent('hello world')  // "hello%20world"
new URLSearchParams({q: 'hello world'}).toString()  // "q=hello+world"

Enter fullscreen mode Exit fullscreen mode

Both are valid in query strings. But + in a path segment means a literal plus sign, not a space. I've seen this break file downloads where filenames contained spaces — the path used +, and the server treated it as a literal +.

Fix: Use %20 when in doubt. It works everywhere.

4. Not encoding path segments

// User uploads a file called "Q1 Report (Final).pdf"
const filename = 'Q1 Report (Final).pdf';

// WRONG
const url = `https://cdn.example.com/files/${filename}`;
// Spaces and parentheses in the path = broken

// RIGHT
const url = `https://cdn.example.com/files/${encodeURIComponent(filename)}`;
// "https://cdn.example.com/files/Q1%20Report%20(Final).pdf"

Enter fullscreen mode Exit fullscreen mode

Most developers remember to encode query parameters but forget that path segments need encoding too. Any user-generated filename, category name, or slug with special characters will break without encoding.

5. Encoding the entire URL with encodeURIComponent

The opposite extreme — encoding everything:

const url = 'https://example.com/search?q=hello';

// Don't do this
encodeURIComponent(url)
// "https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dhello"
// This is not a valid URL anymore

Enter fullscreen mode Exit fullscreen mode

This breaks the URL structure by encoding ://, /, ?, and =. I've seen this in redirect handlers where the full URL was passed through encodeURIComponent "for safety."

Fix: If you need to pass a URL as a parameter value, encode the whole URL with encodeURIComponent. If you need to navigate to a URL, don't encode its structural characters — use the URL API:

const url = new URL('https://example.com/search');
url.searchParams.set('q', 'hello world & more');
url.searchParams.set('redirect', 'https://other.com/page?id=1');
url.toString()
// Everything is encoded correctly, automatically

Enter fullscreen mode Exit fullscreen mode

The modern solution: just use the URL API

Honestly, most of these bugs disappear if you stop string-concatenating URLs:

// Instead of manual encoding...
const url = new URL('https://api.example.com/search');
url.searchParams.set('q', userInput);
url.searchParams.set('page', '1');
url.searchParams.set('callback', 'https://mysite.com/done?status=ok');

fetch(url)  // All encoding handled automatically

Enter fullscreen mode Exit fullscreen mode

The URL and URLSearchParams APIs handle encoding correctly in every case. They're available in all modern browsers and Node.js.


If you want to quickly test how different strings get encoded (or decode a messy URL from server logs), I built a free URL Encoder/Decoder that runs entirely in your browser — nothing gets sent to a server.

For a complete reference of all percent-encoded characters, there's also a URL Encoding Cheat Sheet you can bookmark.

What encoding bugs have bitten you? I'd love to hear your war stories in the comments.