Emre

WFN Üye
Konular
1,644
Mesajlar
1,740
Çözüm
0
Ticaret Puanı
0
Üyelik
9 Ay 3 Gün
Konum
Samsun
Web Sitesi
Var
Alanı
WordPress Uzm.
1/1
Konu sahibi
Formu sayfa yenilenmeden göndermek için formun submit olayını JavaScript ile yakalayıp event.preventDefault() çağırın; ardından alanları FormData ile okuyarak fetch() üzerinden sunucuya gönderin. Sunucudan gelen yanıtı işleyip başarı veya hata mesajını sayfanın ilgili bölümünde gösterdiğinizde kullanıcı aynı sayfada kalır ve gönderimin sonucunu doğrudan görür.

Form gönderimini tarayıcı davranışından ayırma​


Bir form normal şekilde gönderildiğinde tarayıcı formun action adresine istek yapar ve çoğu durumda yeni bir sayfa açar veya mevcut sayfayı yeniler. Sayfa yenilenmesini engelleyen temel yöntem, formun submit olayında event.preventDefault() kullanmaktır.

Bu çağrı tek başına formu sunucuya göndermez; yalnızca tarayıcının varsayılan gönderme davranışını durdurur. Verileri ayrıca JavaScript ile alıp fetch() veya benzeri bir HTTP istemcisiyle sunucuya göndermeniz gerekir.

Aşağıdaki örnek, en küçük çalışır kullanım senaryosudur. Formdaki e-posta adresi sunucuya gönderilir, yanıt beklenir ve sonuç sayfa yenilenmeden mesaj alanına yazılır.

HTML:
<form id="contactForm">
    <label for="email">E-posta adresi</label>
    <input type="email" id="email" name="email" required>

    <button type="submit">Gönder</button>
</form>

<p id="message" aria-live="polite"></p>

<script>
const form = document.querySelector('#contactForm');
const message = document.querySelector('#message');

form.addEventListener('submit', async (event) => {
    event.preventDefault();

    const formData = new FormData(form);

    message.textContent = 'Gönderiliyor...';

    try {
        const response = await fetch('/api/contact', {
            method: 'POST',
            body: formData
        });

        if (!response.ok) {
            throw new Error(`Sunucu hatası: ${response.status}`);
        }

        const result = await response.json();

        message.textContent = result.message || 'Form başarıyla gönderildi.';
        form.reset();
    } catch (error) {
        console.error(error);
        message.textContent = 'Form gönderilemedi. Lütfen tekrar deneyin.';
    }
});
</script>

Bu kodu formun bulunduğu HTML dosyasına ekleyebilirsiniz. /api/contact örnek bir adres olduğundan kendi sunucunuzdaki form işleme uç noktasını kullanmalısınız. Sunucu bu adreste POST isteğini kabul etmeli ve geçerli bir JSON yanıtı döndürmelidir.

Kodun çalışma sırası​


Kodun doğru çalışması için işlem şu sırayla gerçekleşir:
  1. Kullanıcı formu gönderir.
  2. JavaScript, formun submit olayını yakalar.
  3. event.preventDefault() sayfanın yenilenmesini engeller.
  4. new FormData(form) formdaki name özniteliğine sahip alanların değerlerini toplar.
  5. fetch() bu verileri POST isteğiyle sunucuya gönderir.
  6. Sunucu yanıtı döndüğünde JavaScript, yanıtın başarılı veya hatalı olduğunu kontrol eder.
  7. Sonuç, sayfa değiştirilmeden #message alanında gösterilir.
Form alanlarında name özniteliği bulunmazsa ilgili değer FormData içine alınmaz. Örneğin name="email" olmadan yalnızca id="email" kullanılması, alanın seçilebilmesini sağlar ancak gönderilecek veri anahtarını oluşturmaz.

Sunucu JSON döndürmüyorsa​


Örnekte response.json() kullanıldığı için sunucunun JSON biçiminde yanıt vermesi beklenir. Sunucu düz metin döndürüyor ya da yanıt gövdesi kullanılmıyorsa ilgili satırı response.text() olarak değiştirebilirsiniz:

JavaScript:
const response = await fetch('/api/contact', {
    method: 'POST',
    body: new FormData(form)
});

if (!response.ok) {
    throw new Error(`Sunucu hatası: ${response.status}`);
}

const messageFromServer = await response.text();
message.textContent = messageFromServer;

response.ok değeri, HTTP durum kodu başarılı aralıktaysa true olur. Ancak bu değer yalnızca HTTP isteğinin başarılı olup olmadığını gösterir; form verisinin iş kurallarına göre kabul edildiğini tek başına kanıtlamaz. Örneğin sunucu 200 yanıtı verip JSON içinde success: false döndürebilir. Bu nedenle API yanıtının kendi alanlarını da kontrol etmelisiniz.

JavaScript:
const result = await response.json();

if (!result.success) {
    message.textContent = result.message || 'Girilen bilgiler kabul edilmedi.';
    return;
}

message.textContent = result.message || 'Form başarıyla gönderildi.';
form.reset();

Burada success alanının gerçekten sunucu tarafından döndürülmesi gerekir. Sunucunun yanıt biçimi farklıysa kontrolü o biçime göre uyarlayın.

Dosya içeren formlarda doğru gönderim​


Formda dosya yükleme alanı varsa FormData kullanmaya devam edebilirsiniz. Dosyayı ayrıca JSON içine dönüştürmeniz gerekmez. Örneğin:

HTML:
<form id="uploadForm">
    <input type="text" name="title" required>
    <input type="file" name="document" required>
    <button type="submit">Yükle</button>
</form>

<p id="uploadMessage" aria-live="polite"></p>

<script>
const uploadForm = document.querySelector('#uploadForm');
const uploadMessage = document.querySelector('#uploadMessage');

uploadForm.addEventListener('submit', async (event) => {
    event.preventDefault();

    const data = new FormData(uploadForm);
    uploadMessage.textContent = 'Dosya yükleniyor...';

    try {
        const response = await fetch('/api/documents', {
            method: 'POST',
            body: data
        });

        if (!response.ok) {
            throw new Error(`Yükleme başarısız: ${response.status}`);
        }

        uploadMessage.textContent = 'Dosya başarıyla yüklendi.';
        uploadForm.reset();
    } catch (error) {
        console.error(error);
        uploadMessage.textContent = 'Dosya yüklenemedi.';
    }
});
</script>

FormData gönderirken Content-Type başlığını elle multipart/form-data olarak ayarlamayın. Tarayıcı, form verisine ait sınır bilgisini kendisi ekler. Bu başlığı elle yazmak, özellikle dosya yüklemelerinde sunucunun isteği doğru ayrıştıramamasına neden olabilir.

JSON gönderilecekse FormData yerine ne yapılmalı?​


API yalnızca JSON kabul ediyorsa form alanlarını normal bir nesneye dönüştürüp istek gövdesine JSON olarak koyabilirsiniz:

JavaScript:
form.addEventListener('submit', async (event) => {
    event.preventDefault();

    const data = {
        name: form.elements.name.value,
        email: form.elements.email.value
    };

    const response = await fetch('/api/contact', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
    });
});

Bu yöntemde HTML alanlarının name değerlerine değil, JavaScript içindeki form.elements.name kullanımına ve sunucunun beklediği JSON alanlarına dikkat edilir. Dosya gönderecekseniz bu yaklaşım doğrudan uygun değildir; dosyalar için genellikle FormData ve multipart/form-data kullanılır.
Gönderilecek veriUygun yöntemDikkat edilmesi gereken
Metin, seçim ve onay kutularıFormData veya JSONSunucunun beklediği veri biçimini kullanın
Dosya içeren formFormDataContent-Type başlığını tarayıcıya bırakın
JSON API()Content-Type değerini application/json yapın
Seçim yaparken ölçüt, sayfanın yenilenip yenilenmemesi değil, sunucunun hangi veri biçimini beklediğidir. Sunucu multipart/form-data kabul ediyorsa FormData, application/json kabul ediyorsa JSON gönderin.

Başarılı ve hatalı sonuçları doğru yorumlama​


İstek başarıyla tamamlandığında kullanıcıya yalnızca “gönderildi” demek yerine sunucunun döndürdüğü anlamlı mesajı göstermek daha güvenlidir. Gerekirse butonu istek sürerken devre dışı bırakıp aynı formun iki kez gönderilmesini önleyebilirsiniz:

JavaScript:
form.addEventListener('submit', async (event) => {
    event.preventDefault();

    const button = form.querySelector('button[type="submit"]');
    button.disabled = true;
    message.textContent = 'Gönderiliyor...';

    try {
        const response = await fetch('/api/contact', {
            method: 'POST',
            body: new FormData(form)
        });

        const result = await response.json();

        if (!response.ok || result.success === false) {
            throw new Error(result.message || 'Sunucu formu kabul etmedi.');
        }

        message.textContent = result.message || 'Form başarıyla gönderildi.';
        form.reset();
    } catch (error) {
        message.textContent = error.message;
    } finally {
        button.disabled = false;
    }
});

Buradaki sonuçların anlamı birbirinden farklıdır:
  • “Gönderiliyor...” mesajı yalnızca isteğin başlatıldığını gösterir; verinin sunucuya kaydedildiğini kanıtlamaz.
  • Başarılı HTTP yanıtı, sunucunun isteği işlediğini gösterir; e-postanın gerçekten teslim edildiğini veya başka bir arka plan işleminin tamamlandığını kanıtlamayabilir.
  • 400 aralığındaki yanıtlar çoğunlukla eksik, hatalı veya geçersiz istemci verisine işaret eder. Sunucunun döndürdüğü alan hatalarını kullanıcıya gösterip formu düzeltmesini istemelisiniz.
  • 401 veya 403 yanıtları kimlik doğrulama, oturum veya yetki gereksinimiyle ilişkili olabilir. Kullanıcının oturum durumunu ve isteğin gerekli kimlik bilgilerini içerip içermediğini kontrol edin.
  • 500 ve benzeri yanıtlar sunucu tarafındaki işleme sorununu gösterir; aynı veriyi sürekli tekrar göndermek yerine sunucu günlüğündeki hata ve istek zamanı ile inceleme yapın.
  • İstek hiç yanıt vermeden catch bloğuna düşüyorsa ağ bağlantısı, yanlış adres, CORS yapılandırması veya sunucunun erişilebilirliği kontrol edilmelidir.
Form tarayıcı doğrulamasından geçse bile sunucu tarafında doğrulama yapılmalıdır. required, type="email" ve benzeri HTML kuralları kullanıcı deneyimini iyileştirir; güvenlik veya veri bütünlüğü için yeterli değildir. Sunucu, gelen veriyi yeniden doğrulamalı, yetkiyi kontrol etmeli ve beklenmeyen alanları güvenli biçimde ele almalıdır.

Çalışmıyorsa hangi noktaları kontrol etmelisiniz?​


Önce tarayıcının geliştirici araçlarında Network bölümünü açıp form gönderiminde bir HTTP isteği oluşup oluşmadığını kontrol edin. Hiç istek yoksa JavaScript dosyası yüklenmemiş, form seçicisi yanlış yazılmış veya olay dinleyicisi form oluşturulmadan önce çalışmış olabilir. Bu durumda scripti formun sonrasına taşıyın ya da DOM tamamen yüklendikten sonra çalıştırın.

İstek oluşuyor ancak 404 alıyorsanız fetch() içindeki adresi ve uygulamanızın gerçek API yolunu karşılaştırın. 405 yanıtı, URL'nin var olmasına rağmen kullanılan HTTP yönteminin desteklenmediğini gösterebilir. 400 yanıtında sunucunun istediği alan adlarını, boş değerleri ve veri biçimini inceleyin.

İstek tarayıcı tarafından CORS hatasıyla engelleniyorsa sorun genellikle JavaScript kodunun kendisinden değil, API sunucusunun farklı bir kaynakta çalışan sayfaya izin vermemesinden kaynaklanır. API sunucusunda doğru kaynak, yöntem ve gerekiyorsa kimlik bilgileri için CORS yapılandırması yapılmalıdır; istemci tarafında rastgele başlık eklemek bu sorunu güvenilir biçimde çözmez.

İnceleme veya destek talebi açmanız gerekirse şu bilgileri birlikte iletin: isteğin adresi, HTTP yöntemi, durum kodu, sunucunun döndürdüğü hata gövdesi, gönderilen alan adları ve hatanın oluştuğu zaman. Parola, erişim anahtarı, oturum çerezi veya kişisel verileri paylaşmayın. Bu bilgiler, sorunun form kodunda mı, API adresinde mi, doğrulamada mı yoksa sunucu tarafında mı olduğunu ayırmayı sağlar.

Sık sorulan sorular​

() formu sunucuya gönderir mi?​

Hayır. event.preventDefault() yalnızca tarayıcının varsayılan gönderme ve sayfa yenileme davranışını durdurur. Veriyi ayrıca fetch() gibi bir yöntemle sunucuya göndermeniz gerekir.

fetch kullanırken formun action özniteliği gerekli midir?​

JavaScript içinde istek adresini doğrudan fetch() ile veriyorsanız formun action özniteliği kullanılmayabilir. Ancak JavaScript devre dışı kaldığında çalışacak bir geri dönüş davranışı istiyorsanız action ve method değerlerini yine tanımlayıp JavaScript ile normal gönderimi engelleyebilirsiniz.

Form gönderildikten sonra alanları ne zaman temizlemeliyim?​

Alanları yalnızca sunucudan başarı yanıtı aldıktan sonra form.reset() ile temizleyin. İstek başarısızken formu sıfırlarsanız kullanıcı hatayı düzeltmek için girdiği bilgileri yeniden yazmak zorunda kalır.

Sayfa yenilenmiyorsa verinin kaydedildiği kesin midir?​

Hayır. Sayfanın yenilenmemesi yalnızca gönderimin asenkron yapıldığını gösterir. Kaydın başarılı olduğunu anlamak için HTTP yanıtını ve sunucunun uygulamaya özel başarı alanını kontrol edin; gerekiyorsa sunucunun döndürdüğü kayıt kimliği veya güncel kayıt bilgisiyle işlemi doğrulayın.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Foruma git ?

Bu konuyu görüntüleyen kullanıcılar

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic