Samstag, 20 Dezember 2025

Diese Woche am beliebtesten

Vertiefendes Material

Node.js Formular

Mit unserem Leserbrief Formular kannst du ganz einfach Feedback, Anregungen oder Fragen von deiner Community sammeln und strukturiert verwalten. Die Lösung basiert auf Node.js und speichert die eingehenden Nachrichten sicher auf deinem Server, ohne externe Dienste einzubinden.

Das Script bietet:

  • Ein übersichtliches Formular mit Feldern für Name, E-Mail-Adresse, Betreff und Nachricht
  • Eine sichere Speicherung der Einträge in einer JSON-Datei, direkt auf deinem Server
  • Optionale Anonymisierung von Einsendungen
  • Eine klare Bestätigung für Nutzer:innen nach dem Absenden
  • Einen Endpunkt zum Auslesen aller Leserbriefe für interne Auswertungen

So kannst du Feedback direkt einholen, organisieren und für die Weiterentwicklung deiner Inhalte nutzen. Perfekt geeignet für Blogs, Online-Magazine oder Communities, die Wert auf den Dialog mit ihren Leser:innen legen.

const express = require('express');
const fs = require('fs').promises;
const path = require('path');
const app = express();
app.use(express.json()); // erwartet application/json
app.use(express.urlencoded({ extended: true })); // form-urlencoded
const DATA_DIR = path.join(__dirname, 'data');
const DATA_FILE = path.join(DATA_DIR, 'leserbriefe.json');
function validateInput({ name, email, subject, message }) {
  if (!message || typeof message !== 'string' || message.trim().length < 5) {
    return 'Die Nachricht muss mindestens 5 Zeichen enthalten.';
  }
  if (!email || typeof email !== 'string' || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
    return 'Bitte gib eine gültige E-Mail-Adresse an.';
  }
  if (!subject || subject.trim().length === 0) {
    return 'Bitte gib einen Betreff an.';
  }
  return null;
}
async function ensureDataFile() {
  try {
    await fs.mkdir(DATA_DIR, { recursive: true });
    try {
      await fs.access(DATA_FILE);
    } catch {
      await fs.writeFile(DATA_FILE, '[]', 'utf8');
    }
  } catch (err) {
    console.error('Fehler beim Anlegen des Datenverzeichnisses:', err);
    throw err;
  }
}
app.post('/leserbrief', async (req, res) => {
  try {
    const { name = '', email = '', subject = '', message = '', anonymous = false } = req.body;
    const err = validateInput({ name, email, subject, message });
    if (err) return res.status(400).json({ ok: false, error: err });
    const safe = {
      name: String(name).trim(),
      email: String(email).trim(),
      subject: String(subject).trim(),
      message: String(message).trim(),
      anonymous: Boolean(anonymous),
      receivedAt: new Date().toISOString()
    };
    if (safe.anonymous) safe.name = 'Anonym';
    await ensureDataFile();
    const raw = await fs.readFile(DATA_FILE, 'utf8');
    const entries = JSON.parse(raw || '[]');
    entries.push(safe);
    await fs.writeFile(DATA_FILE, JSON.stringify(entries, null, 2), 'utf8');
    return res.json({ ok: true, message: 'Danke! Dein Leserbrief wurde empfangen.' });
  } catch (e) {
    console.error('Serverfehler:', e);
    return res.status(500).json({ ok: false, error: 'Serverfehler' });
  }
});
app.get('/leserbriefe', async (req, res) => {
  try {
    await ensureDataFile();
    const raw = await fs.readFile(DATA_FILE, 'utf8');
    return res.type('application/json').send(raw);
  } catch (e) {
    console.error(e);
    res.status(500).json({ ok: false });
  }
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server läuft auf http://localhost:${PORT}`));
Dreamcodes Redaktion
Dreamcodes Redaktion
Jeder auf Dreamcodes bereitgestellte Codeschnipsel sowie jede Tutorial Anleitung basiert auf geprüften Best Practices und fundierter Praxiserfahrung. Ziel ist es, ein belastbares technisches Fundament bereitzustellen und keine unausgereiften oder experimentellen Lösungen zu veröffentlichen. Die konkrete Nutzung, Integration, Anpassung und Absicherung der Inhalte obliegt jedoch dem Anwender. Vor dem produktiven Einsatz sind sämtliche Inhalte eigenverantwortlich zu prüfen, zu testen und gegebenenfalls abzusichern. Dreamcodes stellt die technische Grundlage zur Verfügung, die finale Umsetzung und Verantwortung verbleibt beim Nutzer.
Nächstes Tutorial

Vielleicht einen Blick WERT?