JavaScript URL エンコーディング完全ガイド

·Front-end & Node.js Developer·レビュー担当Sophie Laurent·公開日

無料の URLエンコーダー をブラウザで直接使用 — インストール不要。

URLエンコーダー をオンラインで試す →

検索 URL を構築したり、リダイレクトパスをクエリパラメータとして渡したり、 OAuth 認可リクエストを構築したりする際、 & =、スペースなどの特殊文字は、 URL エンコードしないと URL を静かに破損させます。 JavaScript には 3 つの組み込みアプローチがあります—— encodeURIComponent() encodeURI()、および URLSearchParams——それぞれ異なるユースケース向けに設計されており、 間違ったものを選ぶことが、コードレビューで私が出会ったほとんどのエンコーディングバグの根本原因です。 コードを書かずに素早く一度だけエンコードするには、 ToolDeck の URL Encoder がブラウザで即座に処理します。このガイドでは 3 つのアプローチすべてを詳しく解説します (JavaScript ES2015+ / Node.js 10+):それぞれをいつ使うか、スペースや予約文字の扱いの違い、 実際の Fetch と API パターン、CLI の使用方法、および最も微妙な本番バグを引き起こす 4 つの間違いについて説明します。

  • 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 で許可されていないか特別な意味を持つ文字を 安全な表現に変換します。 各安全でないバイトは、パーセント記号と 2 桁の16進数——その文字の ASCII コード——に置き換えられます。 スペースは %20 に、アンパサンドは %26 に、スラッシュは %2F になります。

常に安全でエンコードされない文字は非予約文字と呼ばれます: 文字 A–Z と a–z、数字 0–9、および 4 つの記号 - _ . ~。 それ以外はすべて、データとして使用する場合にエンコードする必要があるか、 URL 自体の構造的な役割を持ちます(たとえば / はパスセグメントを区切り、&はクエリパラメータを区切ります)。 実際の結果として、クエリパラメータに「無線キーボード & マウス」のような製品名が含まれる場合、 生のまま渡すと URL 構造が壊れます。

Before · text
After · text
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() は JavaScript における URL エンコーディングの主力関数です。 非予約セット(A–Z、a–z、0–9、- _ . ! ~ * ' ( ))を除くすべての文字をエンコードします。 重要なのは、URL で構造的な意味を持つすべての文字をエンコードすることです——& =? #/—— これにより、パラメータのでの使用が安全になります。 インポートは不要で、すべての JavaScript 環境でグローバル関数として利用できます。

最小限の動作例

JavaScript (browser / Node.js)
// 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 をクエリパラメータとしてエンコード

JavaScript
// 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 文字のエンコード

JavaScript
// 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))
// %E7%94%B0%E4%B8%AD%E5%A4%AA%E9%83%8E

console.log(encodeURIComponent(productTitle))
// %E6%9D%B1%E4%BA%AC%20wireless%20adapter

console.log(encodeURIComponent(reviewText))
// %E8%89%AF%E3%81%84%E8%A3%BD%E5%93%81%20%E2%80%94%20%E5%AE%8C%E7%92%A7%E3%81%AB%E5%8B%95%E4%BD%9C%E3%81%99%E3%82%8B

// Decoding back
console.log(decodeURIComponent('%E7%94%B0%E4%B8%AD%E5%A4%AA%E9%83%8E'))
// 田中太郎
注意:encodeURIComponent() は JavaScript エンジンの内部 UTF-16 文字列エンコーディングを使用し、 その後、文字の各 UTF-8 バイトを個別にエンコードします。 ü(U+00FC)のような文字は %C3%BC にエンコードされます。なぜなら、その UTF-8 表現は 2 バイト(0xC3 と 0xBC)だからです。 これは正しく、URI 標準に従っています——サーバーは UTF-8 バイトシーケンスを元のコードポイントにデコードすることが期待されています。

JavaScript URL エンコーディング関数——文字リファレンス

3 つのネイティブエンコーディングアプローチは、エンコードする文字が異なります。 以下の表は、最も問題になりやすい文字の出力を示しています:

文字URL での役割encodeURIComponent()encodeURI()URLSearchParams
Space単語区切り%20%20+
&パラメータ区切り%26kept%26
=キー=値%3Dkept%3D
+エンコードされたスペース(フォーム)%2B%2B%2B
?クエリ開始%3Fkept%3F
#フラグメント%23kept%23
/パス区切り%2Fkept%2F
:スキーム / ポート%3Akept%3A
@認証区切り%40kept%40
%パーセントリテラル%25%25%25
~非予約keptkeptkept

重要な列は、& = に対する encodeURIComponent() encodeURI() の違いです:encodeURI() はそれらをそのままにします。 これは完全な URL をエンコードする場合は正しいですが、 これらの文字を含むをエンコードする場合は致命的です。

encodeURI() — URL 構造を維持する場合

encodeURI()完全な URL をエンコードするために設計されています—— URI の有効な構造的部分であるすべての文字を保持します:スキーム(https://)、 ホスト、パス区切り文字、クエリ区切り文字、フラグメント識別子。 パスセグメントにスペースや非 ASCII 文字を含む可能性がある URL を受け取り、 その構造をそのままにしておく必要がある場合に使用します。

ユーザー提供の URL をサニタイズ

JavaScript
// 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 文字列を処理する場合、URL コンストラクタは通常 encodeURI() よりも良い選択です——URL を正規化し、 構造を検証し、各コンポーネントにアクセスするためのクリーンな API を提供します。encodeURI() は、文字列結果が必要で、 入力が構造的に有効な URL であることがすでにわかっている場合のために残しておいてください。

URLSearchParams — クエリ文字列のモダンなアプローチ

URLSearchParams は、モダンな JavaScript で クエリ文字列を構築・解析する慣用的な方法です。 すべてのモダンブラウザと Node.js 10+ でグローバルに利用でき、 エンコーディングを自動的に処理します——プレーンなキーと値のペアで作業するだけで、 正しい出力が生成されます。重要な詳細として: application/x-www-form-urlencoded 仕様に従い、 スペースを %20 ではなく + としてエンコードします。 これは正しく広くサポートされていますが、 サーバーが特定の形式を期待する場合は注意してください。

検索リクエスト URL の構築

JavaScript (browser / Node.js 10+)
// 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

受信クエリ文字列の解析

JavaScript
// 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']

JavaScript Fetch リクエストでパラメータを URL エンコードする方法

本番コードで URL エンコーディングが最もよく登場するのは fetch() の呼び出し内です—— リクエスト URL の構築か、リクエストボディにフォームデータを送信する場合です。 それぞれのシナリオに適した正しいアプローチがあります。

GET リクエスト——クエリパラメータのエンコード

JavaScript (browser / Node.js 18+)
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 エンコード

JavaScript
// 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 リダイレクト URI、webhook コールバック URL、CDN 署名付きリクエストパラメータの検査に便利です。

Node.js とシェルによるコマンドライン URL エンコーディング

シェルスクリプト、CI パイプライン、または簡単なデバッグのために、 完全なスクリプトを書かずに動作するいくつかのコマンドラインアプローチがあります。

bash
# ── 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 ライブラリ(週間 npm ダウンロード数 3000 万超)は、 実際に使用されているクエリ文字列パターンの全範囲を処理します: ブラケット表記によるネストされたオブジェクト(filters[status]=active)、 繰り返しキー、カスタムエンコーダー、設定可能な配列シリアライゼーション形式。

bash
npm install qs
# or
pnpm add qs
JavaScript
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 を使用してください。

よくある間違い

本番コードベースでこれらの 4 つの間違いを繰り返し見てきました—— ほとんどは値に特殊文字が含まれる場合にのみ表面化するサイレント失敗であり、 まさにユニットテストをすり抜けて実際のユーザーデータでのみ現れるバグの典型です。

間違い 1 — クエリパラメータ値に encodeURI() を使用

問題: encodeURI() & =、または + をエンコードしません。 値にこれらの文字が含まれると、クエリ文字列の構文として解釈され、 サイレントにパラメータを分割または上書きします。 修正: 個々の値には常に encodeURIComponent() を使用してください。

Before · JavaScript
After · JavaScript
// ❌ 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 を受け取ります。 修正: 最初にデコードしてから再エンコードするか、値が二度エンコードされないようにしてください。

Before · JavaScript
After · JavaScript
// ❌ 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 — URLSearchParams と encodeURIComponent の + / %20 の違いを考慮しない

問題: URLSearchParams はスペースを +(application/x-www-form-urlencoded)としてエンコードし、encodeURIComponent() %20 を使用します。 同じ URL 内で両方を混在させると——たとえば、URLSearchParams の出力に事前エンコードされた文字列を追加する場合—— 一部のパーサーを混乱させる不整合なエンコーディングが生成されます。 修正: 1 つのアプローチを選び、URL 構築関数全体で一貫して使用してください。

Before · JavaScript
After · JavaScript
// ❌ 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 — スラッシュを含むパスセグメントのエンコードを忘れる

問題: REST パスセグメントとして使用されるリソース識別子(ファイルパスの reports/2025/q1.pdf など)には、 サーバールーターがパス区切り文字として解釈する / 文字が含まれており、 存在しないエンドポイントにルーティングされます。 修正: スラッシュを含む可能性があるパスセグメントには常に encodeURIComponent() を使用してください。

Before · JavaScript
After · JavaScript
// ❌ 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

JavaScript URL エンコーディングメソッド——クイック比較

メソッドスペースのエンコード& = ? のエンコード# / : のエンコードユースケースインストール
encodeURIComponent()%20✅ yes✅ yes個々のパラメータ値のエンコードNo
encodeURI()%20❌ no❌ no完全な URL 文字列のサニタイズNo
URLSearchParams+✅ yes✅ yesクエリ文字列の構築と解析No
URL constructorコンポーネントで自動autoauto完全な URL の構築と正規化No
qs library%20(設定可能)✅ yes✅ yesクエリ文字列のネストされたオブジェクトと配列npm install qs

ほとんどの場合、選択は 3 つのシナリオに絞られます。 構造化データから複数パラメータのクエリ文字列を構築する場合は URLSearchParams を使用してください—— 最も安全で可読性が高い選択肢です。 テンプレートリテラル URL で単一の値をエンコードする場合、パスセグメントの場合、 またはスペースに + ではなく %20 を期待するシステム(AWS S3 署名 URL など)の場合は、encodeURIComponent() を使用してください。 クエリ文字列が URLSearchParams でネイティブに表現できないネストされたオブジェクトや配列を持つ場合のみ、 qs を使用してください。

よくある質問

JavaScript における encodeURIComponent() と encodeURI() の違いは何ですか?
encodeURIComponent() は非予約セット(A–Z、a–z、0–9、- _ . ! ~ * ' ( ))を除くすべての文字をエンコードします。& = ? # / : などの構造的文字も含まれます。個々のクエリパラメータ値やパスセグメントのエンコードに設計されています。encodeURI() は構造的な URL 文字を保持します——& = ? # / : @ はエンコードしません——なぜならそれは構造を壊さずに完全な URL をサニタイズするために設計されているからです。& や = を含む値に encodeURI() を使用することは、静かなデータ破損の一般的な原因です。
URLSearchParams がスペースを %20 ではなく + としてエンコードするのはなぜですか?
URLSearchParams は application/x-www-form-urlencoded 仕様(元々は HTML フォームの送信から派生)に従っており、スペースを %20 ではなく + としてエンコードします。+ と %20 はどちらもクエリ文字列内のスペースの有効な表現であり、ほとんどのサーバーは両方を受け入れます。ただし、一部の API——特に AWS Signature v4、Google APIs、カスタム REST バックエンド——は %20 を要求します。そのような場合は、encodeURIComponent() を使用してクエリ文字列を手動で構築するか、URLSearchParams の出力に対して params.toString().replace(/\+/g, '%20') を呼び出してください。
JavaScript でスラッシュを含むパスセグメントを URL エンコードするにはどうすればいいですか?
encodeURIComponent() を使用してください——/ を %2F としてエンコードし、パス全体を単一のセグメントにします。encodeURI() は / をエンコードしないため、ルーターが本物のパス区切り文字として扱います。これは REST API でパス位置にリソース識別子を使用する場合に重要です:ファイルパス(reports/2025/q1.pdf)、S3 オブジェクトキー、複合 ID(org/team/member)。エンコード後:encodeURIComponent('reports/2025/q1.pdf') → 'reports%2F2025%2Fq1.pdf'。
JavaScript でパーセントエンコードされた URL パラメータをデコードするにはどうすればいいですか?
個々のパラメータ値には decodeURIComponent() を使用するか、URLSearchParams に自動的に処理させてください。new URLSearchParams(window.location.search).get('key') を実行すると、値はすでにデコードされています——再び decodeURIComponent() を呼び出す必要はありません。URLSearchParams の外でエンコードされた生の文字列を受け取った場合のみ、直接 decodeURIComponent() を呼び出してください。例えば、カスタムヘッダーや手動で解析した URL フラグメントから受け取った場合などです。注意:decodeURIComponent() はベアの % 文字のような不正な形式のシーケンスに対して URIError をスローします——入力がユーザーデータから来る場合は try/catch でラップしてください。
URLSearchParams を使って { filters: { status: "active" } } のようなネストされたオブジェクトをエンコードできますか?
いいえ。URLSearchParams はフラットなキーと値のペアのみをサポートします。各値に .toString() を呼び出すことでネストされたオブジェクトをシリアライズしますが、これは "[object Object]" を生成します——静かに間違った結果です。ネストされた構造には、qs ライブラリを使用してください:qs.stringify({ filters: { status: 'active' } }) は filters%5Bstatus%5D=active(ブラケット表記)を生成し、Express、Rails、Django REST Framework で理解されます。あるいは、ネストされたデータを JSON 文字列としてシリアライズして単一のパラメータ値として渡してください:params.set('filters', JSON.stringify({ status: 'active' }))。
Fetch API はクエリパラメータを自動的に URL エンコードしますか?
いいえ。fetch() は URL 文字列を受け取り、そのままネットワーク層に渡します——クエリパラメータを解析またはエンコードしません。エンコードされていない値を URL 文字列に連結すると、特殊文字がリクエストを破損させます。正しいパターンは、fetch() に渡す前に URLSearchParams または encodeURIComponent() で URL を構築することです:const url = new URL('/api/search', base); url.searchParams.set('q', userInput); const res = await fetch(url)。URL コンストラクタと URLSearchParams を組み合わせることで、クリーンな API での安全な自動エンコーディングが実現します。

関連ツール

コードを書かずにワンクリックでエンコードまたはデコードするには、 文字列を直接 URL Encoder に貼り付けてください——ブラウザでパーセントエンコーディングとデコーディングを即座に処理し、 エンコードされた出力を fetch 呼び出しやターミナルにコピーする準備ができています。

AC
Alex ChenFront-end & Node.js Developer

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.

SL
Sophie Laurent技術レビュアー

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.