URL Kodlama ve Çözme
URL adreslerini kodlayın ve çözün. encodeURI ile encodeURIComponent farkını açıkça seçebilir, Türkçe karakterli adreslerin nasıl kodlandığını görebilirsiniz.
Tek bir sorgu değerini veya yol parçasını kodlar. & = ? gibi ayıraçları da kaçırır.
Özet (TL;DR)
- encodeURIComponent tek bir parçayı (sorgu değeri, yol segmenti) kodlar; encodeURI ise tam bir URL için ayraçları korur. İkisini karıştırmak bağlantıları sessizce bozar.
- Form kodlamasında (application/x-www-form-urlencoded) "+" karakteri boşluk anlamına gelir, ama decodeURIComponent bunu bilmez.
- Bozuk bir yüzde dizisi (örneğin tek başına "%") decodeURIComponent içinde URIError fırlatır; yakalanmazsa sayfayı düşürür.
- Yüzde kodlaması karakterler üzerinde değil UTF-8 baytları üzerinde çalışır: "ş" tek karakterdir ama %C5%9F olarak iki bayta kodlanır.
encodeURI ile encodeURIComponent arasındaki gerçek fark
JavaScript iki farklı kodlama fonksiyonu sunar ve aralarındaki fark tercih meselesi değildir. encodeURIComponent bir URL parçasının içinde geçebilecek her ayracı kaçırır: ampersand, eşittir, soru işareti, eğik çizgi. encodeURI ise tam bir adresi kodladığınızı varsayar ve bu ayraçlara dokunmaz, çünkü onları kodlarsa URL yapısını yok eder. Sadece birini sunan bir araç, kullanım durumlarının yarısında yanlış sonuç verir. Bu yüzden burada mod açıkça seçilir.
const deger = 'a&b=c'; encodeURIComponent(deger); // 'a%26b%3Dc' -> sorgu DEĞERİ için doğruencodeURI(deger); // 'a&b=c' -> & ve = korundu // Pratikte fark burada ortaya çıkar:'/ara?q=' + deger; // '/ara?q=a&b=c'// Sunucu bunu q=a ve ayrı bir b=c parametresi olarak okur. '/ara?q=' + encodeURIComponent(deger); // '/ara?q=a%26b%3Dc'// Sunucu q parametresinin değerini 'a&b=c' olarak okur. Doğrusu bu.| Girdi | encodeURIComponent | encodeURI | Ne zaman hangisi |
|---|---|---|---|
| a&b=c | a%26b%3Dc | a&b=c | Sorgu değeri ise component |
| /yol/alt | %2Fyol%2Falt | /yol/alt | Tam URL ise full |
| https://a.com/x y | https%3A%2F%2Fa.com%2Fx%20y | https://a.com/x%20y | Tam adres ise full |
| ödeme#1 | %C3%B6deme%231 | %C3%B6deme#1 | Parça ise component |
| a+b | a%2Bb | a+b | Artı gerçekten artıysa component |
Form kodlaması ve artı işareti tuzağı
HTML formları ve pek çok sorgu dizesi application/x-www-form-urlencoded biçimini kullanır. Bu biçim yüzde kodlamasının yakın akrabasıdır ama tek bir kritik farkı vardır: boşluk %20 yerine + olarak yazılır. Bunun sonucu, + karakterinin artık iki farklı anlam taşımasıdır. Gerçek bir artı işareti göndermek istiyorsanız onu %2B olarak kodlamanız gerekir, yoksa karşı taraf boşluk okur.
// Kodlama: form modunda boşluk + olur, gerçek artı %2B olurencodeURIComponent('bir iki+uc').replace(/%20/g, '+');// 'bir+iki%2Buc' // Çözme: + karakterini boşluğa çevirme işlemi decodeURIComponent'ten ÖNCE// yapılmalıdır, aksi halde literal %2B önce + olur, sonra yanlışlıkla boşluğa döner.const girdi = 'bir+iki%2Buc'; decodeURIComponent(girdi); // 'bir+iki+uc' <-- yanlışdecodeURIComponent(girdi.replace(/\+/g, ' ')); // 'bir iki+uc' <-- doğru // Telefon numaraları bu hatanın klasik kurbanıdır:decodeURIComponent('%2B905551234567'); // '+905551234567'new URLSearchParams('tel=+905551234567').get('tel'); // ' 905551234567' <-- artı gittiUyarı
Türkçe karakterler UTF-8 baytları olarak kodlanır
Yüzde kodlaması karakterleri değil baytları kaçırır. ASCII dışındaki her karakter önce UTF-8 ile baytlara dönüştürülür, sonra her bayt ayrı ayrı %XX biçiminde yazılır. Türkçe harfler UTF-8 içinde iki bayt tuttuğu için tek harf iki yüzde dizisine açılır. Bu, kodlanmış bir URL'nin gözle okunmasını zorlaştırır ama davranış tamamen öngörülebilirdir.
encodeURIComponent('ş'); // '%C5%9F' (iki bayt)encodeURIComponent('ı'); // '%C4%B1'encodeURIComponent('İ'); // '%C4%B0'encodeURIComponent('ğ'); // '%C4%9F'encodeURIComponent('a'); // 'a' (ASCII kodlanmaz) encodeURIComponent('çiçek'); // '%C3%A7i%C3%A7ek' // Bir emoji dört bayt tutar:encodeURIComponent('🚀'); // '%F0%9F%9A%80'Alan adının kendisi ayrı bir konudur. https://çiçek.com gibi bir adreste alan adı yüzde kodlamasıyla değil, punycode ile taşınır: tarayıcı bunu https://xn--iek-3lac.com biçimine çevirir. Yüzde kodlaması yalnızca yol, sorgu ve fragman kısımları için geçerlidir. Türkçe alan adlarıyla çalışıyorsanız sunucu tarafında karşılaştırma yaparken her iki gösterimi de normalleştirmeniz gerekir.
Çözme sırasında oluşan hatalar
decodeURIComponent geçersiz bir girdiyle karşılaştığında sessizce geçmez, URIError fırlatır. Tek başına duran bir yüzde işareti, eksik kalmış bir bayt dizisi veya geçersiz bir UTF-8 kombinasyonu bunu tetikler. React uygulamasında yakalanmayan böyle bir hata, doğrudan hata sınırına ulaşıp ekranı boşaltır. Bu araç çözme işlemini her zaman try/catch içinde çalıştırır ve hatayı normal bir doğrulama sonucu olarak gösterir.
Bozuk yüzde dizileri genellikle elle düzenlenmiş bağlantılardan, kırpılmış günlük kayıtlarından veya yüzde işaretini kaçırmadan yapıştıran arayüzlerden gelir. Kullanıcıdan gelen sorgu dizesini işleyen her sunucu ve istemci kodunun bu ihtimali hesaba katması gerekir, çünkü tek bir bozuk parametre tüm isteğin ayrıştırılmasını düşürebilir. Node tarafında da davranış aynıdır: URLSearchParams bozuk diziyi sessizce olduğu gibi bırakırken, decodeURIComponent aynı girdide istisna fırlatır. İki katmanın farklı davranması, hatanın nerede oluştuğunu bulmayı zorlaştırır.
decodeURIComponent('%'); // URIError: URI malformeddecodeURIComponent('%E0%A4%A'); // URIError: eksik üçüncü baytdecodeURIComponent('%ZZ'); // URIError: geçersiz onaltılık // Doğru kullanım:function guvenliCoz(metin) { try { return { ok: true, deger: decodeURIComponent(metin) }; } catch { return { ok: false, hata: 'Bozuk yüzde dizisi' }; }} // Kodlama tarafında da tek bir hata kaynağı vardır: eşi olmayan vekil karakter.encodeURIComponent('\uD800'); // URIError: UTF-8 karşılığı yokSıkça Sorulan Sorular
- Yapıştırdığım metin bir sunucuya gönderiliyor mu?
- Hayır. Kodlama ve çözme tarayıcınızdaki JavaScript içinde çalışır. Hiçbir ağ isteği yapılmaz; sayfa yüklendikten sonra bağlantınızı kesseniz bile araç çalışmaya devam eder. Bu, imza veya oturum belirteci içeren URL parçalarını incelerken önemlidir.
- Tam URL modunu ne zaman kullanmalıyım?
- Elinizde şemasıyla birlikte bütün bir adres varsa ve yalnızca boşluk gibi geçersiz karakterlerin temizlenmesini istiyorsanız tam URL modunu seçin. Sadece bir sorgu parametresinin değerini veya tek bir yol segmentini kodluyorsanız parça modunu kullanın; aksi halde değerin içindeki ampersand yeni bir parametre gibi davranır.
- Bir metni iki kez kodlarsam ne olur?
- Yüzde işaretinin kendisi kodlanır ve %20 gibi bir dizi %2520 olur. Çift kodlama, birbirine zincirlenmiş proxy veya yönlendirme katmanlarında sık görülür. Belirtisi çıktıda %25 ile başlayan dizilerdir; bunu görüyorsanız girdi zaten kodlanmıştır ve bir kez çözülmesi gerekir.
- URLSearchParams kullanmak daha mı iyi?
- Sorgu dizesinin tamamını oluşturuyorsanız evet, çünkü kaçırma işlemini sizin yerinize yapar ve form kodlaması kurallarına uyar. Ancak URLSearchParams boşluğu artı olarak yazar ve gelen artıyı boşluk olarak okur. Tek bir değeri elle kodlayacaksanız encodeURIComponent daha öngörülebilirdir.
- Neden bazı karakterler hiç kodlanmıyor?
- RFC 3986 harfleri, rakamları ve tire, alt çizgi, nokta, tilde karakterlerini ayrılmamış karakter olarak tanımlar. Bunların kodlanmasına gerek yoktur ve kodlanmış hali ile ham hali aynı anlama gelir. encodeURIComponent bu kümeye ek olarak ünlem, yıldız, tek tırnak ve parantezleri de olduğu gibi bırakır.