HTML <form> öğesi, kullanıcıdan bilgi toplayıp bir sunucuya gönderen etkileşimli alanları bir arada tutan bölümdür. Formun nereye gideceğini action, hangi HTTP yöntemiyle gideceğini method, POST ile gönderilen verinin nasıl kodlanacağını enctype belirler; yanıtın nerede açılacağını target, tarayıcı doğrulamasının atlanıp atlanmayacağını novalidate söyler.
Bu yazıda form öğesinin bütün özniteliklerini, gönderim sırasında tarayıcının hangi alanları pakete koyduğunu, form dışındaki bir alanı forma nasıl bağlayacağınızı, gizli alanların ne işe yaradığını ve en sık yapılan hataları göreceksiniz. Alanların kendisi için input türleri rehberine, etiketler için label ve fieldset yazısına bakabilirsiniz.
form öğesi ne işe yarar?
Bir form, tek başına ekranda pek bir şey göstermez; asıl görevi içindeki denetimleri (<input>, <select>, <textarea>, <button>) tek bir gönderim birimi hâline getirmektir. Kullanıcı bir gönder düğmesine bastığında tarayıcı bu birime ait alanları toplar, ad ve değer çiftlerine dönüştürür ve action adresine yollar.
MDN sayfasındaki teknik özete göre form bir akış içeriği (flow content) öğesidir ve akış içeriği kabul eden her yere konabilir. İçine yine akış içeriği alır; tek bir istisna vardır: bir formun içinde başka bir <form> bulunamaz. Başlangıç ve bitiş etiketlerinin ikisi de zorunludur. Örtük ARIA rolü form olur; izin verilen başka roller search, none ve presentation ile sınırlıdır.
<form action="/abonelik" method="post">
<label for="ad">Adınız</label>
<input type="text" id="ad" name="ad" required />
<label for="eposta">E-posta adresiniz</label>
<input type="email" id="eposta" name="eposta" required />
<button type="submit">Abone ol</button>
</form>Bu örnekte iki zorunlu alan ve bir gönder düğmesi var. Düğmeye basıldığında tarayıcı önce required ve type="email" kurallarını denetler, sorun yoksa ad ve eposta adlı iki alanı POST isteğinin gövdesine koyup /abonelik adresine gönderir.
action özniteliği: veri nereye gider?
action, gönderimi işleyecek URL adresidir. Göreli ya da mutlak bir adres verebilirsiniz. MDN örneklerinde action hiç yazılmamış formlar isteği mevcut sayfanın adresine yollar; yani bu öznitelik yoksa veri, formun bulunduğu sayfaya geri gönderilir.
Formun adresi tek bir düğme için değiştirilebilir: <button>, <input type="submit"> ve <input type="image"> üzerindeki formaction, o düğmeyle yapılan gönderimde formun action değerini ezer. Ayrıntılar için button etiketi yazısına bakın. Bir istisnayı da bilin: method="dialog" kullanıldığında action tamamen yok sayılır, çünkü bu durumda hiçbir veri sunucuya gitmez.
method: get, post ve dialog

method büyük küçük harf ayrımı yapmadan yalnızca üç değer alır. Varsayılan get değeridir. GET ile gönderimde form verisi action adresinin sonuna bir ? işaretinden sonra eklenir. MDN, yan etkisi olmayan (aynı isteği tekrar göndermenin bir şeyi değiştirmediği) formlar için bu yöntemi önerir; arama formu tipik örnektir.
post seçildiğinde veri URL yerine isteğin gövdesinde taşınır. Bir hesaba giriş, sipariş verme veya yorum kaydetme gibi sunucuda durum değiştiren işlemler ve herkese açık olmaması gereken bilgiler için bu yöntem uygundur. Üçüncü değer dialog ise yalnızca form bir <dialog> içindeyken anlam taşır: gönderimde iletişim kutusu kapanır, bir submit olayı tetiklenir, fakat veri gönderilmez ve form temizlenmez. Bu kullanım dialog etiketi yazısında ayrıntılı anlatılıyor.
| Değer | Veri nerede taşınır | Tipik kullanım |
|---|---|---|
| get (varsayılan) | URL sonunda, ? işaretinden sonra | Arama, filtreleme, yan etkisi olmayan formlar |
| post | İstek gövdesinde | Giriş, kayıt, sipariş, dosya yükleme |
| dialog | Hiçbir yere gönderilmez | dialog içindeki formu kapatmak |
<!-- GET: /ara?q=kedi gibi bir adres oluşur -->
<form action="/ara" method="get" role="search">
<label for="q">Sitede ara</label>
<input type="search" id="q" name="q" />
<button>Ara</button>
</form>Bu arama formunda kullanıcı kedi yazıp gönderirse tarayıcı /ara?q=kedi adresini açar. Veri adresin parçası olduğu için ortaya çıkan sonuç sayfası her URL gibi kopyalanıp yeniden açılabilir; aynı nedenle veri adres çubuğunda görünür. MDN, giriş bilgileri gibi herkese açık olmaması gereken verilerde POST kullanılmasını söyler; parolalar GET ile gönderilmemelidir.
Gönderilen veri nasıl oluşur?
Tarayıcı gönderim anında formun sahip olduğu denetimleri tek tek dolaşır ve her biri için bir ad=değer çifti üretir. Burada name özniteliği kritik rol oynar. MDN, name resmî olarak zorunlu olmasa da onu zorunlu saymanızı öğütler: adı olmayan ya da adı boş olan bir alanın değeri gönderilmez.
Pakete girmeyen başka durumlar da var. Devre dışı bırakılmış (disabled) alanlar, işaretlenmemiş onay kutuları ve radyo düğmeleri ve sıfırlama düğmeleri veriye eklenmez. Onay kutusu ve radyo düğmesi yalnızca işaretliyse gönderilir; value yazılmamışsa varsayılan değer on olur. Bu konuyu checkbox ve radio yazısında örneklerle bulabilirsiniz.
MDN içerik kategorileri rehberi, form verisini oluşturabilen öğeleri "submittable" (gönderilebilir) olarak adlandırır: <button>, <input>, <select> ve <textarea>. <output> ve <fieldset> forma bağlı olabilir ama değerleri gönderilmez. Düğmeler de ancak gönderimi başlatan düğme olduklarında kendi name ve value çiftini ekler.
enctype: POST verisinin kodlanması

enctype yalnızca method="post" olduğunda devreye girer ve gönderimin MIME türünü belirler. Üç değer vardır:
application/x-www-form-urlencoded: varsayılan değerdir. Ad ve değerler yüzde kodlamasıyla tek bir metin hâline getirilir, boşluklar+olur.multipart/form-data: form bir<input type="file">içeriyorsa bu değeri kullanmanız gerekir; dosyalar ancak bu kodlamayla taşınabilir.text/plain: MDN bunu hata ayıklama amaçlı bir seçenek olarak tanımlar; gerçek gönderimlerde kullanılmamalıdır.
Dosya yükleme formlarının tam kurulumu input file yazısının konusudur. enctype değeri de tek bir düğme için formenctype ile değiştirilebilir.
<form action="/profil" method="post" enctype="multipart/form-data">
<label for="foto">Profil fotoğrafı</label>
<input type="file" id="foto" name="foto" accept="image/*" />
<button type="submit">Yükle</button>
</form>target: yanıt nerede açılır?
target, gönderimden sonra gelen yanıtın hangi tarama bağlamında (sekme, pencere veya iframe) gösterileceğini belirler. Bir iframe ya da pencere adı yazabileceğiniz gibi alt çizgiyle başlayan özel anahtar kelimeleri de kullanabilirsiniz:
_self: varsayılandır; yanıt formun bulunduğu bağlamda açılır._blank: yanıt yeni, adsız bir bağlamda açılır. MDN bu davranışınrel="noopener"ile aynı olduğunu, yaniwindow.openerdeğerinin ayarlanmadığını belirtir._parent: bir üst bağlamda açılır; üst yoksa_selfgibi davranır._top: en üst düzey bağlamda açılır; üst yoksa yine_selfgibi davranır._unfencedTop: yalnızca fenced frame içine gömülmüş formlarda geçerlidir ve yanıtı çerçevenin dışındaki en üst bağlama taşır; tarayıcı desteği için MDN uyumluluk tablosuna bakın.
novalidate ve tarayıcı doğrulaması
Bir form gönderilmeye çalışıldığında tarayıcı içindeki alanların kurallarını (required, pattern, min, maxlength vb.) denetler ve geçersiz bir alan varsa gönderimi durdurup ilk hatalı alanda bir mesaj gösterir. novalidate mantıksal (Boolean) bir özniteliktir; eklendiğinde bu etkileşimli doğrulama yapılmaz. Form düzeyinde açık bırakılan doğrulama tek bir düğmede formnovalidate ile kapatılabilir; "Taslak olarak kaydet" düğmeleri bunun klasik örneğidir.
MDN Constraint validation rehberinde iki önemli not daha var: JavaScript ile form.submit() çağırmak doğrulamayı tetiklemez ve veri kurallara uymasa da gider; doğrulama isteniyorsa gönder düğmesine click() çağrısı yapılmalıdır. Ayrıca istemci tarafındaki doğrulama hiçbir zaman sunucu tarafı denetimin yerini tutmaz; kötü niyetli biri HTML kurallarını kolayca atlatabilir. Doğrulama özniteliklerinin tamamı form doğrulama yazısında anlatılıyor.
autocomplete, name, accept-charset ve rel
Form öğesinin gönderimle doğrudan ilgisi olmayan birkaç özniteliği daha vardır:
autocomplete:onveyaoffalır ve içindeki alanların varsayılan otomatik doldurma davranışını belirler. Alanların kendiautocompletedeğeri formdakini ezer. MDN, tarayıcıların giriş formu olduğundan şüphelendikleri formlardaoffdeğerini çoğunlukla yok saydığını not eder. Ayrıntı: autocomplete yazısı.name: formun adıdır. Boş olamaz ve belgedeki formlar arasında benzersiz olmalıdır. Bu addocument.formsüzerinde formu gösteren bir özellik hâline gelir.accept-charset: sunucunun kabul ettiği karakter kodlamasıdır. Belirtim yalnızca büyük küçük harf duyarsızUTF-8değerine izin verir.rel: formun oluşturduğu bağlantının türünü belirtir;noopener,noreferrer,nofollow,external,help,search,licensegibi değerleri boşlukla ayırarak alır.accept: MDN bu özniteliği kullanımdan kaldırılmış (deprecated) olarak işaretler; bunun yerine dosya alanındaacceptkullanılmalıdır.
Form dışındaki alanları forma bağlamak
Bir denetim normalde içinde bulunduğu en yakın <form> ile ilişkilidir. Sayfa düzeni gereği bir alanı formun dışına koymanız gerekiyorsa o alana form özniteliği ekleyip değer olarak formun id değerini yazabilirsiniz. Bu öznitelik <button>, <fieldset>, <input>, <object>, <output>, <select> ve <textarea> üzerinde çalışır. Değer bir formun id değeri değilse yok sayılır ve bir denetim yalnızca tek bir forma bağlanabilir.
<form id="giris" action="/giris" method="post">
<label>Kullanıcı adı <input type="text" name="kullanici" /></label>
</form>
<!-- Form dışında ama giris formuna ait -->
<label>Parola <input form="giris" type="password" name="parola" /></label>
<button form="giris" type="submit">Giriş yap</button>Gönder düğmesine basıldığında kullanici ve parola birlikte gider. Dikkat edilmesi gereken nokta şu: form özniteliği kalıtılmaz. Bir <fieldset> öğesine form="giris" yazmak yalnızca fieldset öğesini bağlar; içindeki alanlar için özniteliği ayrıca yazmanız gerekir.
Erişilebilirlik: form bir yer işareti olabilir
Ekran okuyucular sayfadaki büyük bölümler arasında "yer işareti" (landmark) denilen bölgelerle hızlıca gezinir. MDN ARIA form rolü sayfasına göre <form> öğesi ancak erişilebilir bir adı varsa form yer işareti olarak sunulur. Bu adı aria-label, aria-labelledby veya title ile verebilirsiniz. Sayfada birden fazla form varsa her birinin adı farklı ve tercihen görünür olmalıdır.
Ad yazarken rolü tekrar etmeyin: ekran okuyucu zaten "form" der, bu yüzden aria-label="İletişim formu" gibi bir ad "iletişim formu form" şeklinde okunabilir. Arama formlarında form rolü yerine daha özel olan search rolü önerilir; bunun için forma role="search" ekleyebilir ya da formu <search> öğesiyle sarabilirsiniz (semantik etiketler yazısı). Bir <div> üzerine role="form" yazmak da mümkündür, ama MDN çok iyi bir nedeniniz yoksa gerçek <form> öğesini kullanmanızı ister; çünkü form olmayan bir öğe kendi başına gönderilemez ve gönderimi JavaScript ile sizin kurmanız gerekir.
<form action="/yorum" method="post" aria-labelledby="yorum-baslik">
<h2 id="yorum-baslik">Yorum bırakın</h2>
<label for="yorum">Yorumunuz</label>
<textarea id="yorum" name="yorum" rows="4"></textarea>
<button type="submit">Gönder</button>
</form>Sık yapılan hatalar

- İç içe form yazmak: form içinde form geçersizdir. İki ayrı gönderim gerekiyorsa formları yan yana koyun ve gerekirse alanları
formözniteliğiyle bağlayın. - name unutmak: adı olmayan alan gönderilmez; sunucuda "veri gelmiyor" sorununun en yaygın nedenidir.
- Dosya yüklerken enctype yazmamak: varsayılan kodlama dosya içeriğini taşımaz;
multipart/form-datavepostbirlikte gerekir. - Parolayı GET ile göndermek: veri adrese eklenir ve adres çubuğunda görünür; bu tür veriler için POST kullanın.
- Formdaki ikinci düğmeye type yazmamak: form içindeki
<button>varsayılan olarak gönder düğmesidir; "Önizle" gibi bir düğme formu beklenmedik şekilde gönderebilir. - Gizli alana güvenmek: fiyat, yetki veya kullanıcı kimliği gibi değerleri gizli alandan okuyup doğrulamadan kullanmak ciddi bir açık doğurur.
- Yalnızca istemci doğrulamasına güvenmek: sunucu her alanı yeniden denetlemeli ve hatalı biçimde 400 yanıtı dönmelidir.
Sık Sorulan Sorular
action yazmazsam form nereye gider?
Form, bulunduğu sayfanın adresine gönderilir. MDN örneklerinde action içermeyen GET ve POST formları isteği mevcut URL adresine yollar.
GET mi POST mu kullanmalıyım?
Sonucu paylaşılabilir bir adres olması gereken, sunucuda bir şeyi değiştirmeyen formlarda GET; giriş, kayıt, ödeme, dosya yükleme gibi durum değiştiren veya gizli bilgi taşıyan formlarda POST uygundur.
novalidate eklersem doğrulama tamamen kaybolur mu?
Tarayıcının gönderim anındaki etkileşimli doğrulaması yapılmaz ve hata balonları çıkmaz. Kuralları JavaScript ile kendiniz denetleyebilirsiniz; sunucu tarafı denetim her durumda gereklidir.
Bir sayfada birden fazla form olabilir mi?
Evet, yeter ki birbirinin içine yerleştirilmesinler. Her formun kendi action değeri ve gönder düğmesi olur; erişilebilirlik için her birine farklı bir ad vermek iyi olur.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: HTML öğrenme rehberi · input türleri · label ve fieldset · button etiketi · form doğrulama · dosya yükleme · web sayfası oluşturma rehberi