E-Mail

Aufbau von MIME-Mails

21. August 2007
von

Wer via Skript nicht nur reine Textmails versendet, sondern auch HTML-Formatierungen einsetzen und Dateianhänge verschicken will, muss einen ganz bestimmten Aufbau beachten, damit die Nachrichten in allen Mail-Clients korrekt dargestellt werden.

Eine Textmail ist leicht verschickt, im Prinzip werden lediglich die Mail-Adresse des Empfängers, ein Betreff und der Nachrichtentext benötigt. Diese werden dann beispielsweise in PHP der Funktion mail() als Argumente übergeben. Schwieriger wird es allerdings, wenn die Mail Sonderzeichen enthält, gar mit HTML formatiert ist oder ein Dateianhang mitgeschickt werden soll. Hier müssen bestimmte Konventionen eingehalten werden, damit der Empfänger mit diesem Datenbrocken überhaupt etwas anfangen kann. Wenn Sie nicht auf fertige Klassen oder Anwendungen zurückgreifen, müssen Sie die Mail von Hand zusammenbauen.

Eine Mail besteht aus drei Teilen, dem

  • Envelope. Er enthält wichtige Daten wie den Absender und den Empfänger, die der Mail Transfer Agent (MTA) für den Transport und die Zustellung der Mail benötigt.
  • Header. Er enthält eine Vielzahl von Angaben, die allerdings nicht für die Zustellung der Mail genutzt werden. Die Daten können daher von denen im Envelope abweichen. Der Mail-Client zeigt normalerweise nicht alle Header-Daten an, sondern nur Absender, Empfänger, Betreff und Datum.
  • Body. Dies ist der eigentliche Inhalt der Mail, also der Nachrichtentext inklusive aller Formatierungen und Dateianhänge.

Wie Header und Body aufgebaut werden müssen, ist in den Multipurpose Internet Mail Extensions, kurz MIME, festgelegt. Diese liefern dem Empfänger auch Informationen darüber, welche Daten geschickt wurden und wie sie kodiert sind.

Die Definition des Content-Types
Damit der Mail-Client des Empfängers weiß, dass es sich bei der Mail um eine MIME-Mail und nicht etwa nur einen einfachen ASCII-Text handelt, muss im Header der Mail darauf hingewiesen werden. Der Header könnte dann beispielsweise so aussehen:

From: absender@absenderdomain.de
To: empfaenger@empfaengerdomain.de
Subject: blabla
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="=_abgrenzung"

Der Content-Type multipart/alternative zeigt an, dass die nachfolgenden Blöcke im Body der Mail die gleichen Informationen beinhalten, aber unterschiedliche Formate haben. Üblicherweise handelt es sich um die HTML-Version der Mail und eine Textversion für Mail-Clients, die kein HTML anzeigen können oder dürfen. Es gibt auch noch andere Content-Typen – je nachdem welcher Art die nachfolgenden Daten sind. Eine Übersicht über die mehr als 100 Content-Typen findet sich auf den Webseiten der IANA. Hier die wichtigsten:

  • application/msexcel für Excel-Dateien
  • application/msword für Word-Dateien
  • application/pdf für PDF-Dateien
  • application/zip für ZIP-Dateien
  • image/gif für Bilder im Format GIF
  • image/jpeg für Bilder im Format JPEG
  • image/png für Bilder im Format PNG
  • multipart/alternative für gleichwertige Daten, von denen nur ein Teil angezeigt wird (entweder die Text- oder die HTML-Version einer Mail)
  • multipart/mixed für gleichwertige Daten, die zusammen angezeigt werden (etwa eine Mail mit mehreren Anhängen)
  • multipart/related für Daten, die zusammen gehören (etwa eine HTML-Mail mit eingebundenem Bild)
  • text/html für HTML-Dateien oder HTML-formatierte Mails
  • text/plain für Textdateien oder Mails mit Plain Text
  • text/richtext für Richtext-Dateien

Die einzelnen Teile einer MIME-Mail werden durch die als boundary definierte Zeichenkette voneinander getrennt und enthalten ihrerseits noch einmal eine Art Sub-Header, der wie der übrige Mail-Inhalt einfach in den Body geschrieben wird. In diesem Sub-Header wird dann für den folgenden Teil erneut ein Content-Typ angegeben und – da der Teil der Mail ebenfalls aus mehreren Teilen bestehen kann – gegebenenfalls auch eine weitere Boundary.

Die Boundary kann frei definiert werden, man sollte allerdings darauf achten, dass die Zeichenkette nirgendwo sonst in einer Mail vorkommen kann. Jeder Teil der Mail beginnt mit der Boundary, der zwei Striche (–) vorangestellt werden. Nach dem letzten Teil folgt erneut eine Boundary, ebenfalls mit den zwei Strichen zu Beginn, aber auch mit zwei abschließenden Strichen, um dem Mail-Client zu zeigen, dass kein weiterer Teil mehr folgt. Ein Beispiel:

// Mail-Header
From: absender@absenderdomain.de
To: empfaenger@empfaengerdomain.de
Subject: blabla
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="=_abgrenzung"

// Mail-Body
// Textteil der Mail
–=_abgrenzung
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

Hier der eigentliche Text der Mail.

// HTML-Teil der Mail
–=_abgrenzung
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: base64

Hier der HTML-Quelltext der Mail.

–=_abgrenzung–

Die Kodierung der Mail
Zwei Dinge fallen am oben stehenden Beispiel auf. Zum einen muss bei Textmails nach der Angabe des Content-Typs noch der Zeichensatz festgelegt werden. Hier kommt üblicherweise ISO-8859-1 zum Einsatz, der neben den ASCII-Zeichen auch die meisten westeuropäischen Sonderzeichen umfasst. Zum anderen muss für alle Teile der Mail mit Content-Transfer-Encoding angegeben werden, wie die Daten kodiert sind.

Eine Mail darf nämlich nur als den 7-Bit-ASCII-Zeichen bestehen. Kommen andere Zeichen vor, müssen diese kodiert werden – andernfalls kommt beim Empfänger nur Zeichensalat an. Die einfachste Möglichkeit ist quoted-printable; hier werden die problematischen Zeichen einfach durch ein Gleichheitszeichen und ihren ASCII-Wert ersetzt, etwa =FC für ü. Da damit allerdings nicht alle möglichen Zeichen abgedeckt werden, nimmt man quoted-printable lediglich für Textmails. Andere Daten, insbesondere Dateianhänge, werden meist mit base64 kodiert; in PHP gibt es dafür die Funktion base64_encode().

Die kodierten Zeilen von MIME-Mails dürfen zudem nicht länger als 76 Zeichen sein. Sie müssen also alle 76 Zeichen einen Zeilenumbruch einfügen, was in PHP die Funktion chunck_split() übernimmt.

Dateianhänge und HTML-Mails mit Bildern
Ein Bild an eine Mail anzuhängen, ist nun auch kein Problem mehr. Der Sub-Header für diesen Teil der Mail sähe zum Beispiel so aus:

Content-Type: image/gif; name="bild.gif"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="bild.gif"

Die Content-Disposition kann auch inline sein, dann wird das Bild nicht als Anhang, sondern innerhalb der Mail angezeigt. Soll es innerhalb des HTML-Teils eingebaut werden, wird ihm eine Content-ID zugewiesen: Content-ID: bild1. Über diese kann das Bild dann mit <img src=”cid: bild1″> eingebunden werden, der eigentliche Name des Bildes ist in diesem Fall unwichtig. Der Aufbau einer MIME-Mail mit Textteil und HTML-Teil, der ein Bild enthält, das nicht aus dem Web nachgeladen, sondern als Dateianhang mitgeliefert wird, sähe so aus:

// Mail-Header
From: absender@absenderdomain.de
To: empfaenger@empfaengerdomain.de
Subject: blabla
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="=_abgrenzung1"

// Mail-Body
// Textteil der Mail
–=_abgrenzung1
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

// Hier der kodierte Text der Mail.

// HTML-Teil der Mail
–=_abgrenzung1
Content-Type: multipart/related; boundary=”=_abgrenzung2″

// der eigentliche HTML-Teil
–=_abgrenzung2
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: base64

// Hier der kodierte HTML-Quelltext der Mail.

// ein Bild, das in den HTML-Teil eingebettet wird
–=_abgrenzung2
Content-Type: image/gif; name=”bild.gif”
Content-Transfer-Encoding: base64
Content-ID: bild
Content-Disposition: inline; filename=”bild.gif”

// Hier das base64-kodierte Bild.

–=_abgrenzung2–
–=_abgrenzung1–

Um dann etwa mit PHP eine MIME-Mail zu verschicken, werden Header, Boundaries, Sub-Header und die kodierten Mail-Inhalte in einen String geschrieben – Zeilenumbrüche nicht vergessen! – und dieser der Funktion mail() übergeben. ™

Freier Journalist für Computer-und Internet-Themen. Schrieb unter anderem für verschiedene gedruckte Fachzeitschriften.

6 Kommentare zu „Aufbau von MIME-Mails
  1. [...] Fool". Zur Ausgangsbasis, ich verwende das E-Mail Programm von OS X. Baue das ganze so auf wie hier im Link. Wobei der Bilderteil vernachl

  2. [...] entsprechenden RFCs zu lesen, aber als Einstieg hilft vielleicht auch dieser Artikel schon weiter: Aufbau von MIME-Mails | E-Mail, MIME | Dr. Web Magazin __________________ Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt? [...]

  3. Lea Katharina Hummer am 28. April 2012 um 23:29

    Einfach nur *DANKE* liebe|r Dr.Web! :)
    … Du hast mit dieser Seite und der eine dreistündige verzweifelte Suche und rumprobieren beendet.

  4. BurninLeo am 23. August 2012 um 12:03

    “… zwei Striche (–) vorangestellt …” wird vom CMS in einen Gedankenstrich verwandelt. Ansonsten herzlichen Dank für die immer wieder hilfreichen Artikel zum fixen Nachlesen :)

  5. [...] den Artikel findest du auf Aufbau von MIME-Mails – Dr. Web Magazin – zwar schon ziemlich alt, aber die Techik hat sich da ja nicht [...]

Ein Kommentar? Schön!

Wir freuen uns immer über Leser, die durch nützliche und konstruktive Beiträge zum Thema eine Diskussion anstoßen oder den Artikel mit weiteren Informationen anreichern. Alle Kommentare werden in diesem Sinne moderiert. Zum Kommentar-Fairplay gehört für uns auch der Einsatz von rel="nofollow". Bitte verwenden Sie zudem als Namen weder eine Domain noch ein spamverdächtiges Wort. Vielen Dank!