Datei-Upload-Formular in HTML erstellen: Entwickler-Tutorial
Datei-Upload-Funktionalität ist für moderne Webanwendungen unverzichtbar. Dieses Tutorial führt Sie durch die Erstellung eines sicheren und benutzerfreundlichen HTML-Datei-Upload-Formulars mit Funktionen wie der Auswahl mehrerer Dateien, Fortschritts-Tracking und Drag-and-drop-Unterstützung.
Einführung in HTML-Datei-Upload-Formulare
Mit HTML-Datei-Upload-Formularen können Nutzer Dateien auswählen und auf einen Server hochladen. Moderne Webanwendungen benötigen robuste Datei-Upload-Funktionen für Features wie Profilbilder, Dokumenteneinreichungen und Medien-Sharing. Sehen wir uns an, wie Sie diese Funktionalität effektiv umsetzen.
Ein einfaches Datei-Upload-Formular in HTML einrichten
Erstellen Sie ein einfaches HTML-Datei-Upload-Formular mit dem Element <form> und einem Feld <input type="file">:
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="file-upload" class="form-label">Select file:</label>
<input
type="file"
id="file-upload"
name="file"
accept=".jpg,.jpeg,.png,.pdf"
aria-describedby="file-help"
/>
<div id="file-help" class="form-text">Accepted formats: JPG, PNG, PDF (max 10MB)</div>
<button type="submit">Upload File</button>
</form>
Wichtige Attribute:
enctype="multipart/form-data"ermöglicht Datei-Uploads- Das Attribut
acceptschränkt die Dateitypen ein - ARIA-Attribute verbessern die Barrierefreiheit
Einzelne und mehrere Datei-Uploads handhaben
Aktivieren Sie die Auswahl mehrerer Dateien und implementieren Sie ein Fortschritts-Tracking:
<form id="upload-form" action="/upload" method="post" enctype="multipart/form-data">
<label for="file-upload">Select files:</label>
<input type="file" id="file-upload" name="files[]" multiple accept=".jpg,.jpeg,.png,.pdf" />
<div id="upload-progress" class="progress" hidden>
<div class="progress-bar" role="progressbar" aria-label="Upload progress" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<button type="submit">Upload Files</button>
</form>
<script>
const form = document.getElementById('upload-form')
const progress = document.getElementById('upload-progress')
const progressBar = progress.querySelector('.progress-bar')
form.addEventListener('submit', async (e) => {
e.preventDefault()
const formData = new FormData(form)
progress.hidden = false
try {
await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percent = (event.loaded / event.total) * 100
progressBar.style.width = percent + '%'
progressBar.setAttribute('aria-valuenow', String(percent))
}
})
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) resolve()
else reject(new Error('Server rejected the upload'))
}
xhr.onerror = () => reject(new Error('Network error'))
xhr.onabort = () => reject(new Error('Upload canceled'))
xhr.ontimeout = () => reject(new Error('Upload timed out'))
xhr.open('POST', form.action)
xhr.timeout = 30000
xhr.send(formData)
})
console.log('Upload successful')
} catch (error) {
console.error('Upload failed:', error)
alert('Upload failed. Please try again.')
} finally {
progress.hidden = true
}
})
</script>
Zu beachten:
- Bei sehr großen Dateien sollten Sie Chunked Uploads und eine Option zum Abbrechen des Uploads implementieren.
- Stellen Sie für den Produktivbetrieb sicher, dass Fortschritts-Tracking und Dateivalidierung serverseitig unterstützt werden.
Den Datei-Upload-Button anpassen
Erstellen Sie eine moderne, gestaltete Datei-Upload-Oberfläche:
<div class="upload-container">
<button type="button" id="choose-files" class="upload-button">
<svg aria-hidden="true" width="24" height="24">
<path d="M12 2l4 4h-3v9h-2V6H8l4-4z" />
</svg>
Choose Files
</button>
<input type="file" id="file-upload" multiple hidden />
<div id="file-list" class="file-list"></div>
</div>
<style>
.upload-button {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
background: #0066cc;
color: white;
border-radius: 4px;
cursor: pointer;
transition: background 0.2s;
}
.upload-button:hover {
background: #0052a3;
}
.file-list {
margin-top: 16px;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
</style>
<script>
const fileInput = document.getElementById('file-upload')
const fileList = document.getElementById('file-list')
document.getElementById('choose-files').addEventListener('click', () => fileInput.click())
function updateFileList() {
fileList.innerHTML = ''
Array.from(fileInput.files).forEach((file) => {
const item = document.createElement('div')
item.textContent = `${file.name} (${formatFileSize(file.size)})`
fileList.appendChild(item)
})
}
fileInput.addEventListener('change', updateFileList)
function formatFileSize(bytes) {
if (bytes === 0) return '0 B'
const k = 1024
const sizes = ['B', 'KiB', 'MiB', 'GiB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`
}
</script>
Clientseitige Validierung hinzufügen
Ersetzen Sie den bisherigen Listener change durch diesen Validierungs-Handler und behalten Sie die
vorhandenen Helper updateFileList() und formatFileSize() bei. Ungültige Auswahlen leeren zudem die
angezeigte Dateiliste. Eine serverseitige Validierung bleibt weiterhin erforderlich:
<script>
const MAX_FILE_SIZE = 10 * 1024 * 1024 // 10MB
const ALLOWED_TYPES = {
'image/jpeg': ['.jpg', '.jpeg'],
'image/png': ['.png'],
'application/pdf': ['.pdf'],
}
function validateFile(file) {
const errors = []
if (file.size > MAX_FILE_SIZE) {
errors.push(`File ${file.name} exceeds 10MB limit`)
}
if (!Object.keys(ALLOWED_TYPES).includes(file.type)) {
errors.push(`File ${file.name} has unsupported type: ${file.type}`)
}
return errors
}
fileInput.addEventListener('change', () => {
const errors = []
Array.from(fileInput.files).forEach((file) => {
errors.push(...validateFile(file))
})
if (errors.length > 0) {
alert(errors.join('\n'))
fileInput.value = ''
updateFileList()
return
}
// Proceed with valid files
updateFileList()
})
</script>
Datei-Upload per Drag-and-drop implementieren
Ergänzen Sie moderne Drag-and-drop-Funktionalität mit verbesserter Barrierefreiheit und Fehlerbehandlung:
<div
id="drop-zone"
class="drop-zone"
role="button"
tabindex="0"
aria-label="Drop files here or click to select"
>
<div class="drop-zone-content">
<svg aria-hidden="true" width="48" height="48">
<path d="M24 4l8 8h-6v18h-4V12h-6l8-8z" />
</svg>
<p>Drop files here or click to select</p>
</div>
</div>
<style>
.drop-zone {
padding: 24px;
border: 2px dashed #ccc;
border-radius: 8px;
text-align: center;
transition: border-color 0.2s;
cursor: pointer;
}
.drop-zone.drag-over {
border-color: #0066cc;
background: rgba(0, 102, 204, 0.1);
}
</style>
<script>
const dropZone = document.getElementById('drop-zone')
function handleDrop(e) {
e.preventDefault()
e.stopPropagation()
try {
const dt = e.dataTransfer
const files = dt.files
handleFiles(files)
} catch (error) {
alert('An error occurred during file drop: ' + error.message)
} finally {
dropZone.classList.remove('drag-over')
}
}
function handleFiles(files) {
const errors = []
Array.from(files).forEach((file) => {
errors.push(...validateFile(file))
})
if (errors.length > 0) {
alert(errors.join('\n'))
return
}
// Update file input and list
const transfer = new DataTransfer()
Array.from(files).forEach((file) => transfer.items.add(file))
fileInput.files = transfer.files
updateFileList()
}
// Event listeners
dropZone.addEventListener('dragover', (e) => {
e.preventDefault()
dropZone.classList.add('drag-over')
})
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('drag-over')
})
dropZone.addEventListener('drop', handleDrop)
// Keyboard accessibility
dropZone.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
fileInput.click()
}
})
// Click also covers pointer activation on touch devices.
dropZone.addEventListener('click', () => {
fileInput.click()
})
</script>
Sicherheitsaspekte
Es ist unerlässlich, Datei-Uploads auch serverseitig zu validieren und zu bereinigen. Erzwingen Sie Beschränkungen der Dateitypen, begrenzen Sie die Dateigrößen sowohl auf dem Client als auch auf dem Server und bereinigen Sie Dateinamen, um potenzielle Sicherheitslücken zu vermeiden. Erwägen Sie außerdem, einen Virenscan zu integrieren, HTTPS für Dateiübertragungen zu verwenden und Ihre Serversoftware aktuell zu halten.
Fazit
Dieses Tutorial zeigt, wie Sie ein modernes, barrierefreies Datei-Upload-Formular mit Erweiterungen wie Fortschritts-Tracking, clientseitiger Validierung und Drag-and-drop-Unterstützung erstellen. Bei sehr großen Dateien sollten Sie Chunked Uploads und eine Option zum Abbrechen des Uploads implementieren, um Nutzererlebnis und Ausfallsicherheit zu verbessern. Führen Sie außerdem stets robuste serverseitige Validierungen und Sicherheitsprüfungen durch.
Für eine robustere Lösung mit fortsetzbaren Uploads und umfassendem Fortschritts-Tracking bietet sich Uppy 4.x an, ein Open-Source-Dateiuploader, der sich nahtlos in moderne Webanwendungen einfügt.
