HTML'de < ve & karakterleri neden özel anlam taşır?
HTML bir biçimlendirme (markup) dilidir ve tarayıcı, sayfanın kaynak kodunu okurken sürekli olarak < karakterini arar: bu karakter göründüğü an, yeni bir etiketin başladığını varsayar. & karakteri de aynı şekilde özel bir anlam taşır, çünkü bir entity referansının başlangıcını işaret eder. Bu yüzden <, > ve & karakterlerini bir sayfada oldukları gibi (harfi harfine bir metin olarak) göstermek istediğinizde bunları doğrudan yazamazsınız — tarayıcı onları markup olarak yorumlamaya çalışır.
Öznitelik (attribute) değerleri içinde de benzer bir sorun ortaya çıkar: bir değeri çift tırnakla sınırlıyorsanız, içindeki bir çift tırnak işareti değeri erken bitirir; tek tırnakla sınırlıyorsanız aynı sorunu bu kez bir tek tırnak işareti yaratır. Bu yüzden özel karakterler yalnızca < , > ve & ile sınırlı değildir — bağlama göre çift tırnak ve tek tırnak da kodlanması gereken karakterler arasına girer.
Named entity mi, numeric character reference mi?
İki farklı entity biçimi vardır. İsimli (named) entity'ler kolay okunur kısa isimlerden oluşur: & işareti & karakterine, < işareti < karakterine, > işareti > karakterine karşılık gelir. Sayısal (numeric) karakter referansları ise bir karakterin Unicode kod noktasını doğrudan kullanır: ondalık biçimde &#NNN; ya da on altılık biçimde &#xHHH; şeklinde yazılır. Örneğin & karakteri ondalık olarak &, on altılık olarak & şeklinde de yazılabilir — ikisi de tarayıcı tarafından aynı karaktere çözülür.
Sayısal biçimin gücü, isimli bir karşılığı olmayan karakterler için de çalışmasıdır: herhangi bir Unicode karakterini, kod noktası bilindiği sürece &#NNN; kuralıyla kodlayabilirsiniz. Örneğin euro işareti (€) için isimli € entity'si tanımlıdır, ama bu isimli karşılığı ezbere bilmeniz gerekmez — aynı karakteri € (ondalık) ya da € (on altılık) olarak da yazabilirsiniz. Apostrof işareti için ise yaygın kullanılan bir isimli entity yoktur; bu yüzden pratikte neredeyse her zaman sayısal ' biçimiyle kodlanır.
| Karakter | Named entity | Numeric (ondalık) | Numeric (on altılık) |
|---|---|---|---|
| < | < | < | < |
| > | > | > | > |
| & | & | & | & |
| çift tırnak (öznitelik içinde) | " | " | " |
| tek tırnak / apostrof | yaygın isimli karşılığı yok | ' | ' |
| © | © | © | © |
HTML entity kodlaması gerçek hayatta nerede işe yarar?
Kullanıcı içeriğini güvenle gösterme
Bir web sitesi, kullanıcıların yazdığı bir yorumu, forum mesajını ya da profil bilgisini sayfaya bastığında, o metnin içinde < ya da & gibi karakterler bulunabilir — kimi zaman masumca (ör. birinin yorumuna 5 < 10 yazması), kimi zaman kötü niyetle (bir <script> etiketi eklemeye çalışmak). Bu metni sayfaya basmadan önce entity'lere çevirmek, tarayıcının onu gerçek bir etiket ya da çalıştırılabilir kod olarak değil, düz metin olarak göstermesini sağlar. Bu, çıktı kodlama (output encoding) adı verilen temel bir güvenlik pratiğidir ve XSS (cross-site scripting) saldırılarına karşı alınan önlemlerden biridir. Tek başına her durumda yeterli değildir — bir değer HTML özniteliği içine ya da bir <script> bloğunun içine yerleştiriliyorsa farklı kodlama kuralları gerekir — ama element gövdesinde metin göstermenin standart ve güvenli yoludur.
Kod parçacıklarını sayfada gösterme
Teknik bir yazıda ya da dokümantasyonda bir HTML ya da JavaScript kod örneği göstermek istediğinizde de aynı sorunla karşılaşırsınız. Kodun içinde <, > ya da & varsa, bunları olduğu gibi yazdığınızda tarayıcı onları gerçek etiket sanıp yorumlamaya çalışır ve kodun bir kısmı görünmez olur ya da sayfanın geri kalanını bozar. Bu yüzden bir <pre> ya da <code> bloğu içinde gösterilecek kod metninin de önce entity'lere çevrilmesi gerekir.
Sık yapılan encoding hataları
- & karakterini en son kodlamak: Karakterleri elle, sırayla değiştirirken önce < ve > işaretlerini < / > yapıp & karakterini en sona bırakırsanız, az önce oluşturduğunuz entity'lerin içindeki & işaretleri de tekrar kodlanır; sonuç &lt; gibi bozuk, çift kodlanmış (double-encoded) bir metin olur. Doğru yaklaşım: & karakterini her zaman ilk kodlamak ya da tüm karakterleri tek bir geçişte değiştiren bir fonksiyon kullanmak.
- Zaten kodlanmış bir metni tekrar kodlamak: Bir metin veritabanında zaten & biçiminde (yani bir kez encode edilmiş olarak) saklanıyorsa ve siz bunu render aşamasında tekrar encode ederseniz, her katmanda bir önek daha eklenir ve sonuç giderek bozulan, gereksiz yere uzamış bir metin olur. Encode işlemi yalnızca ham veri üzerinde ve yalnızca bir kez uygulanmalıdır.
- HTML bağlamını JavaScript string bağlamıyla karıştırmak: HTML entity kodlaması yalnızca tarayıcının HTML olarak ayrıştırdığı alanlarda (element gövdesi, öznitelik değeri) işe yarar. Bir değer bir <script> bloğu içindeki bir JavaScript string'ine yerleştiriliyorsa, tarayıcı o bloğu HTML değil JavaScript olarak ayrıştırır; bu yüzden içindeki bir HTML entity'si decode edilmez, olduğu gibi metin olarak kalır. JS string'e gömülecek değerler için bunun yerine ters bölü işaretiyle kaçış (backslash escape) kullanılır.
- Her zaman isimli bir entity olacağını varsaymak: Az bilinen ya da nadir bir sembolü kodlamak isterseniz her zaman bir isimli karşılığı bulunmayabilir. Bu durumda sayısal karşılık — &#NNN; ya da &#xHHH; — her zaman çalışan evrensel bir yedek yöntemdir.
KEYDAL HTML Entity Kodlayıcı ile hızlı çözüm
Yukarıdaki kuralları elle uygulamak, özellikle & karakterini doğru sırada kodlamak gibi ayrıntılar yüzünden hataya açıktır. KEYDAL'ın HTML entity kodlayıcı/çözücü aracı, düz metni tek tıkla en yaygın beş XML-güvenli karakter (& < > " ') artı birkaç yaygın sembol (© ® ™ € £ ¥) için doğru entity'lere çevirir; decode tarafında ise bunlara ek olarak tüm sayısal karakter referanslarını (&#NNN; ve &#xHHH;) tam olarak çözer. Araç tamamen tarayıcınızda çalışır, girdiğiniz metin hiçbir sunucuya gönderilmez.
Metninizi &, <, > gibi karakterler için HTML entity'lerine çevirin ya da entity kodlu metni tek tıkla orijinaline döndürün.