URL Encode JavaScript — encodeURIComponent()
Используйте бесплатный URL Encode Online прямо в браузере — установка не требуется.
Попробовать URL Encode Online онлайн →При создании URL поиска, передаче пути перенаправления в качестве параметра запроса или формировании OAuth-запроса авторизации такие специальные символы, как &, = и пробелы, незаметно повредят URL, если предварительно не выполнить URL-кодирование. JavaScript предлагает три встроенных способа — encodeURIComponent(), encodeURI() и URLSearchParams — каждый из которых предназначен для своего сценария, и выбор неправильного метода является главной причиной большинства ошибок кодирования, которые я встречал на код-ревью. Для быстрого разового кодирования без написания кода URL Encoder ToolDeck обрабатывает это мгновенно в браузере. Данное руководство подробно рассматривает все три подхода (JavaScript ES2015+ / Node.js 10+): когда применять каждый, чем они отличаются для пробелов и зарезервированных символов, реальные паттерны с Fetch и API, использование в CLI и четыре ошибки, которые вызывают наиболее коварные баги в продакшене.
- ✓encodeURIComponent() — правильный выбор для кодирования значений отдельных параметров: он кодирует все символы, кроме A–Z, a–z, 0–9 и - _ . ! ~ * ' ( )
- ✓encodeURI() кодирует полный URL, сохраняя структурные символы (/ ? # & = :) — никогда не используйте его для отдельных значений
- ✓URLSearchParams автоматически кодирует пары ключ-значение в формате application/x-www-form-urlencoded, где пробелы становятся +, а не %20
- ✓Двойное кодирование — самая распространённая ошибка в продакшене: encodeURIComponent(encodeURIComponent(value)) превращает %20 в %2520
- ✓Библиотека qs нативно обрабатывает вложенные объекты и массивы в строках запроса — стандартный URLSearchParams этого не умеет
Что такое URL-кодирование?
URL-кодирование (формально называемое процентным кодированием, определено в RFC 3986) преобразует символы, недопустимые в URL или имеющие в нём специальное значение, в безопасное представление. Каждый небезопасный байт заменяется знаком процента, за которым следуют две шестнадцатеричные цифры — ASCII-код символа. Пробел становится %20, амперсанд становится %26, косая черта становится %2F.
Символы, которые всегда безопасны и никогда не кодируются, называются незарезервированными символами: буквы A–Z и a–z, цифры 0–9 и четыре символа - _ . ~. Всё остальное либо должно быть закодировано при использовании в качестве данных, либо имеет структурную роль в самом URL (например, / разделяет сегменты пути, а &разделяет параметры запроса). Практическое следствие: название продукта вроде «Беспроводная клавиатура & мышь» в параметре запроса разрушит структуру URL, если передать его в сыром виде.
https://shop.example.com/search?q=Wireless Keyboard & Mouse&category=peripherals
https://shop.example.com/search?q=Wireless%20Keyboard%20%26%20Mouse&category=peripherals
encodeURIComponent() — правильная функция для параметров запроса
encodeURIComponent() — основная рабочая лошадка URL-кодирования в JavaScript. Она кодирует каждый символ кроме незарезервированного набора (A–Z, a–z, 0–9, - _ . ! ~ * ' ( )). Что особенно важно, она кодирует все символы, имеющие структурное значение в URL — &, =, ?, #, / — что делает её безопасной для использования в значениях параметров. Импорт не требуется: это глобальная функция, доступная во всех JavaScript-окружениях.
Минимальный рабочий пример
// Encode a search query parameter that contains special characters
const searchQuery = 'Wireless Keyboard & Mouse'
const filterStatus = 'in-stock'
const maxPrice = '149.99'
const searchUrl = `https://shop.example.com/products?` +
`q=${encodeURIComponent(searchQuery)}` +
`&status=${encodeURIComponent(filterStatus)}` +
`&maxPrice=${encodeURIComponent(maxPrice)}`
console.log(searchUrl)
// https://shop.example.com/products?q=Wireless%20Keyboard%20%26%20Mouse&status=in-stock&maxPrice=149.99Кодирование URL перенаправления в качестве параметра запроса
// The redirect destination is itself a URL — it must be fully encoded
// or the outer URL parser will misinterpret its ? and & as its own
const redirectAfterLogin = 'https://dashboard.internal/reports?view=weekly&team=platform'
const loginUrl = `https://auth.company.com/login?next=${encodeURIComponent(redirectAfterLogin)}`
console.log(loginUrl)
// https://auth.company.com/login?next=https%3A%2F%2Fdashboard.internal%2Freports%3Fview%3Dweekly%26team%3Dplatform
// Decoding on the receiving end
const params = new URLSearchParams(window.location.search)
const next = params.get('next') // Automatically decoded
const nextUrl = new URL(next!) // Safe to parse
console.log(nextUrl.hostname) // dashboard.internalКодирование символов не-ASCII и Unicode
// encodeURIComponent handles Unicode natively in all modern environments
// Each UTF-8 byte of the character is percent-encoded
const customerName = 'Иванов, Алексей'
const productTitle = 'Москва wireless adapter'
const reviewText = 'Отлично — работает безупречно'
console.log(encodeURIComponent(customerName))
// %D0%98%D0%B2%D0%B0%D0%BD%D0%BE%D0%B2%2C%20%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B5%D0%B9
console.log(encodeURIComponent(productTitle))
// %D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0%20wireless%20adapter
console.log(encodeURIComponent(reviewText))
// %D0%9E%D1%82%D0%BB%D0%B8%D1%87%D0%BD%D0%BE%20%E2%80%94%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82%20%D0%B1%D0%B5%D0%B7%D1%83%D0%BF%D1%80%D0%B5%D1%87%D0%BD%D0%BE
// Decoding back
console.log(decodeURIComponent('%D0%98%D0%B2%D0%B0%D0%BD%D0%BE%D0%B2%2C%20%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B5%D0%B9'))
// Иванов, АлексейencodeURIComponent() использует внутреннее кодирование строк JavaScript UTF-16, а затем кодирует каждый UTF-8 байт символа отдельно. Символ й (U+0439), например, кодируется в %D0%B9, поскольку его UTF-8 представление состоит из двух байт: 0xD0 и 0xB9. Это корректно и соответствует стандарту URI — серверы должны декодировать последовательность байт UTF-8 обратно в исходную кодовую точку.Функции URL-кодирования JavaScript — справочник по символам
Три нативных подхода к кодированию различаются именно тем, какие символы они кодируют. В таблице ниже показан результат для наиболее проблематичных символов:
| Символ | Роль в URL | encodeURIComponent() | encodeURI() | URLSearchParams |
|---|---|---|---|---|
| Пробел | разделитель слов | %20 | %20 | + |
| & | разделитель параметров | %26 | kept | %26 |
| = | ключ=значение | %3D | kept | %3D |
| + | закодированный пробел (форма) | %2B | %2B | %2B |
| ? | начало запроса | %3F | kept | %3F |
| # | фрагмент | %23 | kept | %23 |
| / | разделитель пути | %2F | kept | %2F |
| : | схема / порт | %3A | kept | %3A |
| @ | разделитель авторизации | %40 | kept | %40 |
| % | литерал процента | %25 | %25 | %25 |
| ~ | незарезервированный | kept | kept | kept |
Ключевое различие — столбцы encodeURIComponent() и encodeURI() для & и =: encodeURI() оставляет их нетронутыми, что правильно при кодировании полного URL, но катастрофично при кодировании значения, содержащего эти символы.
encodeURI() — когда нужно сохранить структуру URL
encodeURI() предназначен для кодирования полного URL— он сохраняет все символы, являющиеся допустимыми структурными элементами URI: схему (https://), хост, разделители пути, разделители запроса и идентификатор фрагмента. Используйте его, когда получаете URL, который может содержать пробелы или не-ASCII символы в сегментах пути, но нужно сохранить его структуру нетронутой.
Санитизация URL, предоставленного пользователем
// A URL pasted from a document with spaces in the path and non-ASCII chars const rawUrl = 'https://cdn.example.com/assets/product images/München chair.png' const safeUrl = encodeURI(rawUrl) console.log(safeUrl) // https://cdn.example.com/assets/product%20images/M%C3%BCnchen%20chair.png // encodeURIComponent would break it — it encodes the :// and all / characters const broken = encodeURIComponent(rawUrl) console.log(broken) // https%3A%2F%2Fcdn.example.com%2Fassets%2Fproduct%20images%2FM%C3%BCnchen%20chair.png // ↑ Not a valid URL — the scheme and slashes are destroyed
URL обычно является лучшим выбором, чем encodeURI(), для обработки строк URL, введённых пользователем — он нормализует URL, проверяет структуру и предоставляет удобный API для доступа к каждому компоненту. Оставьте encodeURI() для случаев, когда нужен строковый результат и вы уже знаете, что входные данные структурно являются корректным URL.URLSearchParams — современный подход к строкам запроса
URLSearchParams — это идиоматический способ построения и разбора строк запроса в современном JavaScript. Он доступен глобально во всех современных браузерах и Node.js 10+, автоматически выполняет кодирование — вы работаете с обычными парами ключ-значение, а он производит корректный результат. Важная деталь: он следует спецификации application/x-www-form-urlencoded, которая кодирует пробелы как +, а не %20. Это корректно и широко поддерживается, но следует учитывать это, когда ваш сервер ожидает конкретный формат.
Построение URL поискового запроса
// Building a search API URL with multiple parameters
const filters = {
query: 'standing desk',
category: 'office-furniture',
minPrice: '200',
maxPrice: '800',
inStock: 'true',
sortBy: 'price_asc',
}
const params = new URLSearchParams(filters)
const apiUrl = `https://api.example.com/v2/products?${params}`
console.log(apiUrl)
// https://api.example.com/v2/products?query=standing+desk&category=office-furniture&minPrice=200&maxPrice=800&inStock=true&sortBy=price_asc
// Appending additional params after construction
params.append('page', '2')
params.append('tag', 'ergonomic & adjustable')
console.log(params.toString())
// query=standing+desk&...&tag=ergonomic+%26+adjustableРазбор входящей строки запроса
// Both browser (window.location.search) and Node.js (req.url) scenarios
function parseWebhookCallbackUrl(rawSearch: string) {
const params = new URLSearchParams(rawSearch)
return {
eventId: params.get('event_id'), // null if missing
timestamp: Number(params.get('ts')),
signature: params.get('sig'),
redirectUrl: params.get('redirect'), // Automatically decoded
tags: params.getAll('tag'), // Handles repeated keys
}
}
const callbackQuery = '?event_id=evt_9c2f&ts=1717200000&sig=sha256%3Dabc123&redirect=https%3A%2F%2Fdashboard.internal%2F&tag=payment&tag=webhook'
const parsed = parseWebhookCallbackUrl(callbackQuery)
console.log(parsed.redirectUrl) // https://dashboard.internal/
console.log(parsed.tags) // ['payment', 'webhook']Как URL-кодировать параметры в Fetch-запросах JavaScript
Чаще всего URL-кодирование встречается в продакшен-коде внутри вызовов fetch() — либо при построении URL запроса, либо при отправке данных формы в теле запроса. Каждый сценарий имеет свой корректный подход.
GET-запрос — кодирование параметров запроса
async function searchInventory(params: {
sku?: string
warehouse: string
minStock: number
updatedAfter?: Date
}): Promise<{ items: unknown[]; total: number }> {
const searchParams = new URLSearchParams()
if (params.sku) searchParams.set('sku', params.sku)
searchParams.set('warehouse', params.warehouse)
searchParams.set('min_stock', String(params.minStock))
if (params.updatedAfter) searchParams.set('updated_after', params.updatedAfter.toISOString())
const url = `https://inventory.internal/api/items?${searchParams}`
const res = await fetch(url, {
headers: {
'Authorization': `Bearer ${process.env.INVENTORY_API_KEY}`,
'Accept': 'application/json',
},
})
if (!res.ok) {
throw new Error(`Inventory API ${res.status}: ${await res.text()}`)
}
return res.json()
}
const results = await searchInventory({
warehouse: 'eu-west-1',
minStock: 10,
updatedAfter: new Date('2025-01-01'),
})
console.log(`Found ${results.total} items`)POST-запрос — URL-кодирование тела формы
// application/x-www-form-urlencoded POST — used by OAuth token endpoints,
// legacy form-submission APIs, and some webhook providers
async function requestOAuthToken(
clientId: string,
clientSecret: string,
code: string,
redirectUri: string,
): Promise<{ access_token: string; expires_in: number }> {
const body = new URLSearchParams({
grant_type: 'authorization_code',
client_id: clientId,
client_secret: clientSecret,
code,
redirect_uri: redirectUri, // URLSearchParams encodes this automatically
})
const res = await fetch('https://oauth.provider.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body.toString(),
// body: body — also works directly in modern environments (Fetch spec accepts URLSearchParams)
})
if (!res.ok) {
const err = await res.json()
throw new Error(`OAuth error: ${err.error_description ?? err.error}`)
}
return res.json()
}Когда нужно протестировать или отладить закодированный URL без написания скрипта, вставьте исходное значение прямо в URL Encoder — он мгновенно кодирует и декодирует, показывая именно то, что увидят браузер и сервер. Удобно для проверки OAuth redirect URI, URL обратных вызовов вебхуков и параметров подписанных запросов CDN.
URL-кодирование в командной строке с Node.js и Shell
Для shell-скриптов, CI-пайплайнов или быстрой отладки существует несколько подходов командной строки, не требующих написания полного скрипта.
# ── Node.js one-liners — cross-platform (macOS, Linux, Windows) ────────
# encodeURIComponent — encode a single value
node -e "console.log(encodeURIComponent(process.argv[1]))" "Wireless Keyboard & Mouse"
# Wireless%20Keyboard%20%26%20Mouse
# Build a complete query string
node -e "console.log(new URLSearchParams(JSON.parse(process.argv[1])).toString())" '{"q":"standing desk","category":"office-furniture","page":"1"}'
# q=standing+desk&category=office-furniture&page=1
# Decode a percent-encoded string
node -e "console.log(decodeURIComponent(process.argv[1]))" "Wireless%20Keyboard%20%26%20Mouse"
# Wireless Keyboard & Mouse
# ── curl — automatic encoding ───────────────────────────────────────────
# curl --data-urlencode encodes values automatically in GET and POST
curl -G "https://api.example.com/search" --data-urlencode "q=Wireless Keyboard & Mouse" --data-urlencode "category=office furniture"
# ── Python one-liner (available on most systems) ─────────────────────────
python3 -c "from urllib.parse import quote; print(quote(input(), safe=''))"
# (type the string and press Enter)
# ── jq + bash: encode every value in a JSON object ───────────────────────
echo '{"q":"hello world","tag":"node & express"}' | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(new URLSearchParams(d).toString())"
# q=hello+world&tag=node+%26+expressВысокопроизводительная альтернатива: qs
Встроенный URLSearchParams не поддерживает вложенные объекты и массивы — формат строк запроса, используемый многими API и фреймворками. Библиотека qs (30M+ еженедельных загрузок из npm) обрабатывает весь спектр паттернов строк запроса: вложенные объекты с скобочной нотацией (filters[status]=active), повторяющиеся ключи, пользовательские кодировщики и настраиваемые форматы сериализации массивов.
npm install qs # or pnpm add qs
import qs from 'qs'
// URLSearchParams cannot represent this structure natively
const reportFilters = {
dateRange: {
from: '2025-01-01',
to: '2025-03-31',
},
status: ['published', 'archived'],
author: { id: 'usr_4f2a9c1b', role: 'editor' },
workspace: 'ws-platform-eu',
}
// qs produces bracket-notation query strings used by Express, Rails, Django REST
const query = qs.stringify(reportFilters, { encode: true })
console.log(query)
// dateRange%5Bfrom%5D=2025-01-01&dateRange%5Bto%5D=2025-03-31&status%5B0%5D=published&status%5B1%5D=archived&author%5Bid%5D=usr_4f2a9c1b&author%5Brole%5D=editor&workspace=ws-platform-eu
// Human-readable (no encoding) — useful for debugging
console.log(qs.stringify(reportFilters, { encode: false }))
// dateRange[from]=2025-01-01&dateRange[to]=2025-03-31&status[0]=published&status[1]=archived...
// Parsing back
const parsed = qs.parse(query)
console.log(parsed.dateRange) // { from: '2025-01-01', to: '2025-03-31' }
console.log(parsed.status) // ['published', 'archived']Для плоских параметров ключ-значение URLSearchParams — всегда правильный выбор: он встроен, не имеет накладных расходов и универсально поддерживается. Обращайтесь к qs только тогда, когда нужны вложенные структуры, форматы сериализации массивов, отличные от повторяющихся ключей, или вы интегрируетесь с бэкенд-фреймворком, который ожидает строки запроса в скобочной нотации.
Распространённые ошибки
Я неоднократно видел эти четыре ошибки в продакшен-кодовых базах — большинство из них являются скрытыми сбоями, которые проявляются только тогда, когда значение содержит специальный символ, что именно тот вид багов, которые проходят сквозь юнит-тесты и появляются только с реальными пользовательскими данными.
Ошибка 1 — Использование encodeURI() для значений параметров запроса
Проблема: encodeURI() не кодирует &, = и +. Когда значение содержит эти символы, они интерпретируются как синтаксис строки запроса, незаметно разбивая или перезаписывая параметры. Исправление: всегда используйте encodeURIComponent() для отдельных значений.
// ❌ encodeURI does not encode & and = in the value
// "plan=pro&promo=SAVE20" is treated as two separate params
const planName = 'Pro Plan (save=20% & free trial)'
const url = `/checkout?plan=${encodeURI(planName)}`
// /checkout?plan=Pro%20Plan%20(save=20%%20&%20free%20trial)
// ↑ & breaks the query string// ✅ encodeURIComponent encodes & and = safely
const planName = 'Pro Plan (save=20% & free trial)'
const url = `/checkout?plan=${encodeURIComponent(planName)}`
// /checkout?plan=Pro%20Plan%20(save%3D20%25%20%26%20free%20trial)
// ↑ = and & are both encodedОшибка 2 — Двойное кодирование уже закодированной строки
Проблема: Вызов encodeURIComponent() для значения, которое уже закодировано процентами, превращает % в %25, поэтому %20 становится %2520. Сервер декодирует один раз и получает буквальный %20 вместо пробела. Исправление: сначала декодируйте, затем перекодируйте, или убедитесь, что значение никогда не кодируется дважды.
// ❌ encodedParam already contains %20 — encoding again produces %2520
const encodedParam = 'Berlin%20Office'
const url = `/api/locations/${encodeURIComponent(encodedParam)}`
// /api/locations/Berlin%2520Office
// Server sees: "Berlin%20Office" (a literal percent-twenty, not a space)// ✅ Decode first if the value may already be encoded
const maybeEncoded = 'Berlin%20Office'
const clean = decodeURIComponent(maybeEncoded) // 'Berlin Office'
const url = `/api/locations/${encodeURIComponent(clean)}`
// /api/locations/Berlin%20Office — correctОшибка 3 — Игнорирование разницы между + и %20 у URLSearchParams и encodeURIComponent
Проблема: URLSearchParams кодирует пробелы как + (application/x-www-form-urlencoded), тогда как encodeURIComponent() использует %20. Смешивание обоих подходов в одном URL — например, добавление предварительно закодированной строки к выводу URLSearchParams — создаёт непоследовательное кодирование, которое сбивает с толку некоторые парсеры. Исправление: выберите один подход и последовательно применяйте его во всей функции построения URL.
// ❌ Mixed: URLSearchParams uses + for spaces, but we're appending
// a manually-encoded segment that uses %20
const base = new URLSearchParams({ category: 'office furniture' })
const extra = `sort=${encodeURIComponent('price asc')}`
const url = `/api/products?${base}&${extra}`
// /api/products?category=office+furniture&sort=price%20asc
// ↑ two different space encodings in the same URL// ✅ Use URLSearchParams exclusively — consistent encoding throughout
const params = new URLSearchParams({
category: 'office furniture',
sort: 'price asc',
})
const url = `/api/products?${params}`
// /api/products?category=office+furniture&sort=price+ascОшибка 4 — Забыть закодировать сегменты пути, содержащие косые черты
Проблема: Идентификатор ресурса вроде пути к файлу (reports/2025/q1.pdf), используемый как сегмент пути REST, содержит символы /, которые маршрутизатор сервера интерпретирует как разделители пути, направляя запрос к несуществующему конечному адресу. Исправление: всегда используйте encodeURIComponent() для сегментов пути, которые могут содержать косые черты.
// ❌ The file path contains / — the server receives a 3-segment path
// instead of a single resource ID
const filePath = 'reports/2025/q1-financials.pdf'
const url = `https://storage.example.com/objects/${filePath}`
// https://storage.example.com/objects/reports/2025/q1-financials.pdf
// → Server routes to /objects/:year/:filename — 404 or wrong resource// ✅ encodeURIComponent encodes / as %2F — single path segment
const filePath = 'reports/2025/q1-financials.pdf'
const url = `https://storage.example.com/objects/${encodeURIComponent(filePath)}`
// https://storage.example.com/objects/reports%2F2025%2Fq1-financials.pdf
// → Server receives the full file path as one resource identifierМетоды URL-кодирования JavaScript — краткое сравнение
| Метод | Кодирует пробелы как | Кодирует & = ? | Кодирует # / : | Сценарий использования | Требует установки |
|---|---|---|---|---|---|
| encodeURIComponent() | %20 | ✅ да | ✅ да | Кодирование отдельных значений параметров | No |
| encodeURI() | %20 | ❌ нет | ❌ нет | Санитизация полной строки URL | No |
| URLSearchParams | + | ✅ да | ✅ да | Построение и разбор строк запроса | No |
| Конструктор URL | авто по компоненту | авто | авто | Конструирование и нормализация полных URL | No |
| Библиотека qs | %20 (настраиваемо) | ✅ да | ✅ да | Вложенные объекты и массивы в строках запроса | npm install qs |
В подавляющем большинстве случаев выбор сводится к трём сценариям. Используйте URLSearchParams при построении многопараметрических строк запроса из структурированных данных — это самый безопасный и читаемый вариант. Используйте encodeURIComponent() для кодирования одного значения в шаблонном URL, для сегментов пути или для значений в системах, которые ожидают %20 вместо + для пробелов (например, подписанные URL AWS S3). Обращайтесь к qs только тогда, когда строка запроса содержит вложенные объекты или массивы, которые URLSearchParams не может представить нативно.
Часто задаваемые вопросы
Связанные инструменты
Для быстрого кодирования или декодирования без написания кода вставьте вашу строку прямо в URL Encoder — он мгновенно выполняет процентное кодирование и декодирование в вашем браузере, с готовым результатом для копирования в вызов fetch или терминал.
Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.
Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.