URL Ayrıştırma Nedir?
URL ayrıştırma, bir Tekdüzen Kaynak Bulucuyu (Uniform Resource Locator) bireysel bileşenlerine ayırma işlemidir: protokol (şema), ana makine adı, port, yol adı, sorgu parametreleri ve parça tanımlayıcısı. Her URL, RFC 3986 ve WHATWG URL Standardı tarafından tanımlanan bir yapıya uygundur. Bir URL ayrıştırıcısı ham dizeyi okur, sınırlayıcı karakterlere (://, :, /, ?, #, &, =) göre her segmenti tanımlar ve bunları ayrı, erişilebilir alanlar olarak döndürür.
Tarayıcılar, bir adres yazdığınızda veya bir bağlantıya tıkladığınızda URL ayrıştırma işlemi gerçekleştirir. JavaScript URL yapıcısı, Python'un urllib.parse modülü ve Go'nun net/url paketi; aynı yapısal kurallara uyan ayrıştırıcılar uygular. Bir URL'yi ayrıştırmak, URL kodlamanın tersidir: karakterleri güvenli aktarım için dönüştürmek yerine, önceden oluşturulmuş bir URL'yi onu oluşturan parçalara ayrıştırırsınız.
https://api.example.com:8080/v1/users?page=2&limit=10#section gibi tipik bir URL altı farklı bileşen içerir. Sınırlayıcı karakterler — ://, :, /, ?, &, =, ve # — ayrıştırmayı belirleyici kılan unsurlardır: her biri bir sınır işaret eder ve ayrıştırıcının alanları belirsizlik olmadan çıkarmasına olanak tanır.
Çevrimiçi URL Ayrıştırıcı Neden Kullanılır?
Bir URL'yi gözle elle bölmek hataya açıktır; özellikle dize kodlanmış karakterler, birden fazla sorgu parametresi veya standart dışı portlar içerdiğinde. Bu araç, URL'yi tarayıcıların kullandığı WHATWG uyumlu algoritmayla ayrıştırır ve her bileşeni net, kopyalanabilir bir tabloda görüntüler.
URL Ayrıştırıcı Kullanım Senaryoları
URL Bileşen Başvurusu
Aşağıdaki tablo, JavaScript URL yapıcısının bir URL'yi ayrıştırırken döndürdüğü her özelliği göstermektedir. Python'un urlparse sonucunda, Go'nun url.URL yapısında ve PHP'nin parse_url çıktısında da aynı bileşenler bulunur; ancak özellik adları diller arasında farklılık gösterir.
| Özellik | Örnek | Açıklama |
|---|---|---|
| protocol | https: | Scheme including the trailing colon |
| hostname | api.example.com | Domain name or IP address |
| port | 8080 | Port number (empty string if default) |
| pathname | /v1/users | Path starting with / |
| search | ?page=2&limit=10 | Query string including the leading ? |
| hash | #section | Fragment identifier including the leading # |
| origin | https://api.example.com:8080 | protocol + hostname + port |
| host | api.example.com:8080 | hostname + port |
| username | admin | Credentials before @ (rarely used in practice) |
| password | secret | Credentials before @ (avoid in production URLs) |
| href | (full URL) | The complete, serialized URL string |
WHATWG URL Standardı ile RFC 3986 Karşılaştırması
URL'lerin nasıl ayrıştırılması gerektiğini tanımlayan iki belirtim vardır. Temel yapı konusunda hemfikirdirler ancak uç durumlarda ayrışırlar — bu ayrışma, tarayıcınızın bir URL'yi sunucunuzdan farklı şekilde işlemesinin genellikle nedenidir.
Pratikte, çoğu farklılık uluslararası alan adları (IDN), eksik şemalar veya olağandışı karakterler içeren URL'ler ayrıştırılırken ortaya çıkar. WHATWG ayrıştırıcısı IDN ana makine adlarını otomatik olarak Punycode'a dönüştürürken, katı RFC 3986 ayrıştırıcıları bunları reddedebilir. Bu araca bir URL yapıştırırsanız ve sunucu tarafı kodunuzun ürettiğinden farklı sonuçlar görürseniz, WHATWG ile RFC arasındaki fark büyük olasılıkla nedendir.
Kod Örnekleri
Her büyük dilde yerleşik bir URL ayrıştırıcısı vardır. Aşağıdaki örnekler aynı URL'yi ayrıştırır ve bileşenlerini çıkarır. Diller arasındaki küçük adlandırma farklılıklarına dikkat edin: Python, protocol yerine scheme kullanır ve Go, search yerine RawQuery'yi gösterir.
const url = new URL('https://api.example.com:8080/v1/users?page=2&limit=10#section')
url.protocol // → "https:"
url.hostname // → "api.example.com"
url.port // → "8080"
url.pathname // → "/v1/users"
url.search // → "?page=2&limit=10"
url.hash // → "#section"
// Iterate over query parameters
for (const [key, value] of url.searchParams) {
console.log(`${key} = ${value}`)
}
// → "page = 2"
// → "limit = 10"
// Modify and re-serialize
url.searchParams.set('page', '3')
url.toString()
// → "https://api.example.com:8080/v1/users?page=3&limit=10#section"from urllib.parse import urlparse, parse_qs
result = urlparse('https://api.example.com:8080/v1/users?page=2&limit=10#section')
result.scheme # → 'https'
result.hostname # → 'api.example.com'
result.port # → 8080
result.path # → '/v1/users'
result.query # → 'page=2&limit=10'
result.fragment # → 'section'
# Parse query string into a dict
params = parse_qs(result.query)
params['page'] # → ['2']
params['limit'] # → ['10']
# Reconstruct with modifications
from urllib.parse import urlencode, urlunparse
new_query = urlencode({'page': '3', 'limit': '10'})
urlunparse(result._replace(query=new_query))
# → 'https://api.example.com:8080/v1/users?page=3&limit=10#section'package main
import (
"fmt"
"net/url"
)
func main() {
u, err := url.Parse("https://api.example.com:8080/v1/users?page=2&limit=10#section")
if err != nil {
panic(err)
}
fmt.Println(u.Scheme) // → "https"
fmt.Println(u.Hostname()) // → "api.example.com"
fmt.Println(u.Port()) // → "8080"
fmt.Println(u.Path) // → "/v1/users"
fmt.Println(u.RawQuery) // → "page=2&limit=10"
fmt.Println(u.Fragment) // → "section"
// Query params as map
q := u.Query()
fmt.Println(q.Get("page")) // → "2"
fmt.Println(q.Get("limit")) // → "10"
}<?php $url = 'https://api.example.com:8080/v1/users?page=2&limit=10#section'; $parts = parse_url($url); $parts['scheme']; // → "https" $parts['host']; // → "api.example.com" $parts['port']; // → 8080 $parts['path']; // → "/v1/users" $parts['query']; // → "page=2&limit=10" $parts['fragment']; // → "section" // Parse query string into an array parse_str($parts['query'], $params); $params['page']; // → "2" $params['limit']; // → "10"