---
title: 'Dosya Yükleme'
source: 'https://academia.sh/tr/kurslar/web-temelleri-ve-html/dosya-yukleme'
course: "Web'in Temelleri ve HTML"
language: tr
updated: '2026-08-17T18:09:31+00:00'
license: 'CC BY-SA 4.0'
---

# Dosya Yükleme

Dosya alanının ürettiği değer, çok parçalı gönderim kodlamasının gövdedeki karşılığı, kabul türü bildirimi ve boyut sınırının nerede uygulandığı.

Doğrulama, metin ve sayı alanları üzerinde kuruldu. Dosya alanı bu düzenlere uymaz.
Değeri bir dizgi değildir; ikilik içerik taşır, kendi adı ve kendi içerik türü vardır.

Form Yapısı dersinde tanımlanan varsayılan kodlama —`ad=deger` çiftlerinin `&` ile
birleştirilmesi— bu içeriği taşıyamaz. Dosya alanı olan bir formda gönderim kodlaması
değiştirilir.

## Üç Öznitelik

```html
<form action="/olcum/yukle" method="post" enctype="multipart/form-data">
  <p><label for="kayit">Ham kayıt dosyası</label>
     <input id="kayit" name="kayit" type="file" accept=".csv,text/csv" required></p>
  <p><button type="submit">Yükle</button></p>
</form>
```

`enctype="multipart/form-data"` gönderim kodlamasını değiştirir. Yazılmadığında dosya
alanı yalnızca **dosya adını** gönderir; içerik gitmez. Bu, sessizce yanlış çalışan bir
formun en sık nedenidir: form gönderilir, sunucu bir değer alır, ama aldığı şey bir
dizgidir.

`accept` özniteliği, dosya seçicide hangi türlerin öne çıkarılacağını bildirir. Değeri
uzantı listesi, içerik türü listesi ya da ikisinin karışımı olabilir.

`multiple` özniteliği birden çok dosya seçilmesine izin verir; her dosya giriş listesine
aynı adla ayrı bir giriş olarak katılır.

## Gövdenin Biçimi

Aşağıdaki betik bir sunucu açar, aynı iki alanı iki farklı kodlamayla gönderir ve
sunucunun aldığı ham gövdeyi yazdırır. Satır sonları görünür olsun diye `\r\n` dizisi
açıkça yazdırılmıştır.

```js
// dosya.mjs — iki gonderim kodlamasinin govdedeki karsiligi
import { createServer } from "node:http";

// Sinir dizgisi her gonderimde rastgele uretilir; ciktinin yinelenebilir olmasi icin
// yazdirmadan once sabit bir yer tutucuyla degistirilir.
const sunucu = createServer((istek, yanit) => {
  const parcalar = [];
  istek.on("data", (parca) => parcalar.push(parca));
  istek.on("end", () => {
    const govde = Buffer.concat(parcalar);
    const tur = istek.headers["content-type"];
    const sinir = tur.match(/boundary=(.+)$/)?.[1];
    const maskele = (d) => (sinir ? d.split(sinir).join("SINIR") : d);
    console.log("content-type  :", maskele(tur));
    console.log("govde uzunlugu:", govde.length, "bayt");
    console.log("--- ham govde ---");
    console.log(maskele(govde.toString()).replace(/\r\n/g, "\\r\\n\n"));
    console.log("===");
    yanit.writeHead(204).end();
  });
});

sunucu.listen(0, "127.0.0.1", async () => {
  const adres = "http://127.0.0.1:" + sunucu.address().port + "/yukle";

  // enctype="multipart/form-data"
  const veri = new FormData();
  veri.append("istasyon", "kuzey-yamac");
  veri.append("kayit", new Blob(["saat,sicaklik\n07:00,-4.2\n"], { type: "text/csv" }), "olcum.csv");
  await fetch(adres, { method: "POST", body: veri });

  // enctype="application/x-www-form-urlencoded" — ayni iki alan, dosya icerigi olmadan
  await fetch(adres, {
    method: "POST",
    headers: { "content-type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams([["istasyon", "kuzey-yamac"], ["kayit", "olcum.csv"]]).toString(),
  });

  sunucu.close();
});
```

```
content-type  : multipart/form-data; boundary=SINIR
govde uzunlugu: 295 bayt
--- ham govde ---
--SINIR\r\n
Content-Disposition: form-data; name="istasyon"\r\n
\r\n
kuzey-yamac\r\n
--SINIR\r\n
Content-Disposition: form-data; name="kayit"; filename="olcum.csv"\r\n
Content-Type: text/csv\r\n
\r\n
saat,sicaklik
07:00,-4.2
\r\n
--SINIR--\r\n

===
content-type  : application/x-www-form-urlencoded
govde uzunlugu: 36 bayt
--- ham govde ---
istasyon=kuzey-yamac&kayit=olcum.csv
===
```

Çıktıdaki `SINIR` bir yer tutucudur: gerçek sınır dizgisi her gönderimde rastgele
üretilir ve betik onu yazdırmadan önce sabit bir metinle değiştirir. Sınırın metni
gönderen tarafça seçilir; tek koşulu, gövdenin hiçbir yerinde geçmemesidir. Gövde
uzunluğu bu betikte değişmez, çünkü üretilen sınırın uzunluğu sabittir.

Gövde yapısı şöyledir. `Content-Type` başlığında bir **sınır (boundary)** dizgisi
bildirilir. Gövde bu sınırla parçalara ayrılır; her parça kendi başlıklarını, bir boş
satırı ve içeriğini taşır. `Content-Disposition` başlığı alanın adını verir; dosya
alanlarında ayrıca `filename` parametresi bulunur. Dosya parçasında bir de `Content-Type`
başlığı vardır ve dosyanın türünü bildirir. Gövde, sınırın sonuna iki tire eklenmiş
biçimiyle biter.

İki temel fark görünür.

**İçerik kaçırılmaz.** Çok parçalı kodlamada dosya içeriği olduğu gibi taşınır; yüzde
kodlaması uygulanmaz. Ayırma işini sınır dizgisi yapar. İkilik bir dosya, kodlanmadan
gönderilebilir.

**Yük oranı yüksektir.** Aynı iki alan için 36 bayta karşılık 295 bayt kullanılmıştır. Her
parça kendi başlıklarını taşır ve sınır dizgisi her parçada yinelenir. Bu maliyet dosya
büyüdükçe oransal olarak küçülür; ancak dosya alanı olmayan bir formu çok parçalı
kodlamayla göndermek gereksiz bir yüktür.

Çıktının ikinci bölümü, yanlış kodlamanın sonucunu gösterir: `kayit` alanı yalnızca dosya
adını taşır. Sunucu bir değer alır ve içerik yoktur.

## Kabul Türü Bir Kısıt Değildir

`accept` özniteliği dosya seçici penceresini süzer. Süzgeç kullanıcı tarafından
kaldırılabilir ve gönderim belge kullanılmadan da yapılabilir; Yerleşik Doğrulama dersindeki
sonuç burada da geçerlidir.

Dosyanın gerçekten bildirdiği türde olup olmadığı, gövdedeki `Content-Type` başlığından
anlaşılmaz: o başlığı da gönderen taraf yazar. Sunucu türü ancak dosyanın **içeriğine**
bakarak doğrulayabilir — dosya biçimlerinin baş baytlarındaki tanımlayıcı diziler bu iş
içindir.

Uzantıya güvenmek de yeterli değildir. Yüklenen dosya adı sunucuda doğrudan kullanılmaz:
kullanıcıdan gelen ad yol ayıracı içerebilir, var olan bir dosyanın üzerine yazabilir ya
da sunucunun çalıştırdığı bir uzantı taşıyabilir. Güvenli davranış, sunucunun kendi
ürettiği bir ad kullanması ve özgün adı yalnızca üstveri olarak saklamasıdır.

## Alanın Değeri Belgeden Yazılamaz

Dosya alanı, diğer alanlardan bir yönüyle daha ayrılır: değeri belgeden verilemez.
`value` özniteliği yazılsa da yok sayılır, çünkü aksi hâlde bir belge, kullanıcının
diskindeki herhangi bir dosyayı sessizce gönderebilirdi. Alanın değeri yalnızca
kullanıcının seçimiyle oluşur.

Aynı gerekçe dosyanın **yolunu** da gizler. Belgeye açılan bilgi dosyanın adı, boyutu ve
türüdür; bulunduğu dizin değildir. Kullanıcının dizin yapısı, o kullanıcı hakkında bilgi
taşır ve belgeye verilmez.

Bunun bir sonucu, bir formun önceki gönderimden kalan dosyayı yeniden göstermesinin
olanaksız olmasıdır. Doğrulama hatası nedeniyle geri dönülen bir formda diğer alanların
değerleri belgede yeniden yazılabilir; dosya alanı boş kalır ve kullanıcının dosyayı
yeniden seçmesi gerekir. Çok adımlı formlarda bu, dosyanın erken bir adımda yüklenip
sunucuda geçici olarak saklanmasını ve sonraki adımlarda bir kimlikle anılmasını
gerektirir.

## Boyut Sınırı Belgede Bildirilemez

Dosya boyutunu sınırlayan bir öznitelik yoktur. Bunun bir eksiklik değil, tutarlı bir
tasarım olduğu söylenebilir: belgede bildirilen bir sınır zaten uygulanamazdı.

Sınır iki yerde uygulanır. Sunucu, gövdenin tamamını okumadan `Content-Length` başlığına
bakarak isteği reddedebilir ve okurken de bir üst sınır uygulayabilir; bu, belleğin bir
istekle doldurulmasını önler. Sunucu yazılımının kendi yapılandırması da genellikle bir
istek gövdesi üst sınırı taşır.

Kullanıcıya erken geri bildirim vermek isteniyorsa dosya boyutu gönderim öncesinde
davranış katmanında okunabilir; bu bir kolaylıktır, kısıt değildir. Beklenen sınır belgede
metin olarak yazılır — kullanıcı, seçtiği dosyanın reddedileceğini yükleme bittikten sonra
öğrenmemelidir.

## İstasyon Belgesinde

```html
<fieldset>
  <legend>Ham kayıt</legend>
  <p><label for="kayit">Ölçüm dosyası</label>
     <input id="kayit" name="kayit" type="file"
            accept=".csv,text/csv" aria-describedby="kayit-yardim">
     <span id="kayit-yardim">Virgülle ayrılmış değer dosyası, en çok 5 MB.</span></p>
</fieldset>
```

Formun `enctype` özniteliği bu alan eklendiği anda değiştirilmelidir; unutulduğunda form
çalışıyor görünür ve dosya içeriği hiç ulaşmaz.

## Özet

- Dosya alanı olan formda `enctype="multipart/form-data"` yazılır; yazılmadığında yalnızca
  dosya adı gönderilir ve içerik kaybolur.
- Çok parçalı gövde bir sınır dizgisiyle parçalara ayrılır; her parça kendi başlıklarını
  taşır ve içerik kaçırılmadan aktarılır.
- Bu kodlamanın yük oranı yüksektir; dosya alanı olmayan formlarda kullanılmaz.
- `accept` yalnızca dosya seçiciyi süzer; tür denetimi sunucuda, dosyanın içeriğine
  bakılarak yapılır ve yüklenen ad doğrudan kullanılmaz.
- Boyut sınırı belgede bildirilemez; sunucuda uygulanır ve kullanıcıya metinle bildirilir.

## Sonraki Adım

Form bu noktada veri topluyor, doğruluyor ve dosya alabiliyor. Geriye bir soru kalıyor:
gönderim reddedildiğinde kullanıcı ne görüyor? Tarayıcının kendi iletisi tek alanı
gösteriyor, sunucudan dönen hata ise yeni bir belgeyle geliyor. Son ders hata bildirimini
ve odak yönetimini ele alır ve kursu, bu formun erişilebilir sürümünü kurarak kapatır.
