tudorf: Frage zu selfhtml Beispiel "Grafik/Grafiken mit Data-URI"

Hallo Ich sende aus meiner eigenen Software eine HTML Email die ich dann ich outlook 2016 ansehe. Um Bilder zu senden verschicke ich BASE64 kodierte Daten lt. dem Beispiel unter

https://wiki.selfhtml.org/wiki/Grafik/Grafiken_mit_Data-URI#Weblinks

Das Beispiel der Feuerwehr funktioniert bei mit. Das kodierte Bild bzw. der Code wird bei mir aus einer DatenbankBild wird nur als Platzhalter angezeigt ausgelesen und verschickt. Platziere ich das Bild mehrfach hintereinander erscheint auch das Feuerwehrbild mehrfach.

Sobald ich eine ander Datei Kodiere wird nichts mehr angezeigt. Bilder in unterschiedlichen Größen. JPG, Gif und PNG.

Kodiert habe ich hier

Als HTML image und als Data-URI. Beim öffnen der Email ploppt ein Bild auf und ist sofort verschwunden. Dann wird nur noch ein Platzhalter mit Fehlermeldung angezeigt. Das Bild befindet sich lokal auf unserer HD.

Kann mir jemand einen Tip geben? Danke Martin

  1. Hallo tudorf,

    es kann sein, dass das nicht an Dir liegt:

    https://stackoverflow.com/questions/6070196/what-is-data-uri-support-like-in-major-email-client-software

    Der SO Beitrag ist schon alt und hört bei Outlook 2013 auf, es sieht aber so aus als wäre Outlook 2003 ein "Ausrutscher" gewesen.

    Wie bettest Du das Bild ein? HTML Mail mit <img> Element drin?

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf Richtig mit IMG.

      Ich stelle den Text der email mal ein. Der Text wird von mit per Programm erstellt und dann verschickt. Fehlende " oder ähnliches habe ich nicht gefunden. Die IMG daten von data:image/gif;base64,R bis Oe9jNY2Z+O8t lese ich aus der Datenbank. Tausche ich den Inhalt mit dem kodierten Feuerzeugbild aus geht es. Mit diesem geht es nicht.

      <html><body> test Hallo Martin, <br><br><a href= " www.bs-tastatur.de "> <img width=" 400" height=" 400" alt=Infotext 1" src= "data:image/gif;base64,R0lGODlhoRDMDPcAAAAAAAAACAAADAAAEAAAGAAAIAAAJAQEBAAAKAAAMAAAOAAAQAgIAAAASAgICAAATAAAUAAAWQAAXQAAYQwMAAAAaQwMDAAAcQAAeQAAgRAQAAAAhQAAiQAAjRAQEAAAlQAAnQAApQAArgAAthQUFAAAvgAAwhgYAAAAxgAAzgAA1gAA2hgYGAAA3gAA5gAA7gAA9gAA/xwcHCAgACAgICQkAAgI9ggI/ygoACQkJAwM8gwM/ygoKBAQ7hAQ/zAwABgY5jAwMBgY/zg4ADQ0NCAg3iQk2jg4OCAg/0BAACgo1iQk/zw8PCgo/0BAQEhIADAwzkxMADAw/1BQADg4xkhISP8AAExMTDg4/0BAvllZAP8EBFBQUF1dAEhItv8MDFVVVUBA/2FhAP8QEExMsllZWf8UFFBQrkhI/11dXWlpAP8cHExM/2FhYVlZpfogIF1dofokJHFxAGVlZfooKGFhnWlpaVlZ/3l5AG1tbfowMGlplV1d//o0NHFxcfo4OIGBAHFxjYWFAPpAQHl5eWlp/4mJAHl5hfZISH19fY2NAPZMTHFx/4GBfYGBgfZQUIWFeZWVAIWFhfZVVYmJdXl5//ZZWYmJiY2NcfZdXZ2dAI2NjYGB/5WVafZlZZGRkYWF/6WlAPZpafJtbZWVlYmJ/52dYfJxcZmZmY2N/6GhXa6uAKWlWfJ5eZ2dnZWV/6Ghoba2APKBga6uUKWlpfKFhZ2d//KJib6+AKqqqra2SO6NjcLCAO6Rka6urqWl/76+QO6VlcbGALKyssLCPO6dnba2tsbGOK6u/87OAO6hobq6uu6lpc7OMLa2/76+vtbWAO6ursLCwtraAOqystbWKL6+/97eAMbGxtraJOq6usLC/97eIMrKysbG/+bmAOrCws7OzubmGOrGxtLS0s7O/+rKyu7uAO7uENbW1urOzurS0tra2tbW//b2APb2COba2tra/97e3ura2ube3t7e////AObm5ubm/+7u7u7u//b29vb2/////wAAAAAAACwAAAAAoRDMDAAI
      
      hier fehlt was da der Betrag zu viele Zeichen hatte.
      
      /3u90rfeI+SUqx0dSDYXvwOf37WL3J6UD5qPYFkbw/2zowxqmyDida0e7rGeYp846JPd6zufY8AeesWeJEie1/leQaD85ffc7pek1L/a8R8fIPVcI+i+u9deR2YPnV9/1MnT7zvitafX8K/9R5LZ6BMc82/v9BD+y8reytPplwY21VxOP0+9qIdeCWU/iTe/+j2f+88F9JtX9LHT5ovf+H8Eyqn/vYW/Tlo/25m/+a1jeFOe9jNY2Z+O8t"></a><br><br> neu <br>vielen Dank für Ihre Anfrage. In der Anlage erhalten Sie unser       <br>entsprechendes Angebot als PDF-Datei. Wir würden uns freuen, Ihren   <br>Auftrag ausführen zu dürfen.                                         <br>                                                                     <br>Alle Eingabesysteme werden kundenspezifisch hergestellt. Es handelt  <br>sich dabei um                                                        <br>                                                                     <br>- Folientastaturen                                                   <br>- Designfolien                                                       <br>- Bedienfelder auf einer Leiterplatte                                <br>- Frontplatten aus Aluminium mit/ohne Kurzhubtasten                  <br>- Frontplatten mit LCD-Monitor und Touchscreen.                      <br>                                                                     <br>Gerne übernehmen wir auch weiterführende Dienstleistungen für Sie.   <br>                                                                     <br>Wir hoffen, Ihre Vorstellungen in Leistung und Preis getroffen zu    <br>haben. Falls Sie dennoch Änderungswünsche oder Fragen haben sollten, <br>zögern Sie bitte nicht uns anzusprechen, damit wir gegebenenfalls    <br>nacharbeiten können.                                                 <br>                                                                     <br>Für Fragen stehe ich Ihnen gerne zur Verfügung und verweise ebenso   <br>auf unsere Internetpräsenz: <a href="http://www.bs-tastatur.de/">    <br>www.bs-tastatur.de </a> .                                            <br>                                                                     <br>Wir erlauben uns, Sie in den nächsten Tagen anzurufen.               <br><br>Mit freundlichen Grüßen<br>Martin Wagner                 <br><br>BS Deutschland GmbH<br>Matthäusring 3<br>33154 Salzkotten<br>Telefon 02955/ 74749-0<br>Telefax 02955/ 74749-22<br>---------------------------------------------------------------------------------------------------------------------<br><b>BS Deutschland GmbH.,Matthäusring 3, 33154 Salzkotten, NRW/Deutschland</b><br>TEL: 02955/74749-0, FAX: 02955/74749-22, EMail: info@bs-tastatur.de, Internet: http://www.bs-tastatur.de<br>Geschäftsführer: Martin Wagner, Nadine Wagner,  Amtsgericht Paderborn, HRB 9300, USt.-ID.-Nr.: DE 815 080 843,<br>Es gelten unsere AGB die sie unter www.bs-tastatur.de/agb einsehen können.<br>Unsere Datenschutzerklärungen finden Sie unter http://bs-tastatur.de/datenschutzerklaerung.<br>---------------------------------------------------------------------------------------------------------------------<br>Legal Disclaimern Nachrichten mit BS mittels e-Mail dient ausschließlich Informationszwecken.<br>Der Austausch von Nachrichten mit BS mittels e-Mail dient ausschließlich Informationszwecken.<br>Rechtsgeschäftliche Erklärungen dürfen über dieses Medium nicht ausgetauscht werden.können<br>Verfälschungen des ursprünglichen Inhalts dieser Nachricht bei der Datenübertragung können<br>nicht ausgeschlossen werden.-----------------------------------------------------------------------------------------<br><b>---------------------------------------------------------------------------------------------------------------------</b><br>BS Deutschland GmbH<br></body></html>Quelltext hier
      
      1. Ich sehe gerade:

        • data:image/gif

        Hast Du eventuell übersehen, dass Du den Content-Type korrekt setzen/anpassen musst?

        Das könnte ein Grund dafür sein, dass es mal geht (mit einem Pic im binären gif-Format als Ausgangspunkt) - mit jpegs indes nicht.

        1. Ich hatte unterschiedlichste Dateien probiert. JPG, GIF PNG usw.

  2. Moin,

    Das Beispiel der Feuerwehr funktioniert bei mit. Das kodierte Bild bzw. der Code wird bei mir aus einer DatenbankBild wird nur als Platzhalter angezeigt ausgelesen und verschickt. Platziere ich das Bild mehrfach hintereinander erscheint auch das Feuerwehrbild mehrfach.

    Steht das Bild mehrfach Base64-kodiert im Quellcode? Das bläht die Email aber ganz schön auf.

    Sobald ich eine ander Datei Kodiere wird nichts mehr angezeigt. Bilder in unterschiedlichen Größen. JPG, Gif und PNG.

    Du möchtest dich eventuell mit Attachments und Content ID in dem Zusammenhang beschäftigen. Kurz gesagt werden die Bilder Anhänge der Email und können über das Pseudo-Protokoll cid refereniert werden – auch mehrfach.

    Viele Grüße
    Robert

    1. Hallo Rolf das Bild soll nicht mehrfach eingesetzt werden. Ich bin am Fehlersuchen und habe das Bild daher 3x eingefügt. Martin

      1. Hm.

        Also mit einer Graphik geht es, mit einer anderen nicht.

        Da kommen mehrere Möglichkeiten in Betracht:

        • Die Graphik(en) ist mit der/denen es nicht geht, ist/sind von Anfang an „kaputt“.

        Das kannst nur Du prüfen.

        • Oder: Die Graphik(en) wurde(n) durch den Online-Dienst nicht korrekt kodiert oder nicht korrekt empfangen.

        Dann kannst Du OpenSSL für Windows installieren und im Terminal mit openssl base64 < datei.jpg > datei.jpg.base64.txt selbst kodieren, den Inhalt dieser Datei sodann einfügen. Unter Linux kannst Du statt openssl base64 alternativ das Kommandozeilen-Programm base64 in der selben Weise benutzen. Auf Macs (wohl) ebenso.

        Auf dem Webserver kannst das von PHP erledigen lassen. Etwas wie

        $encoded = base64_encode( file_get_contents( $PicFile ) )` 
        

        wäre dann Dein „Freund“. Im Wiki ist übrigens https://www.fastix.org/test/Data-URL-Generator.txt nicht grundlos verlinkt. Stell aber die Schrauben für die Dateigröße höher… dann hast Du Deinen eigenen Online-Generator, der übrigens funktioniert.

        • Dein Anzeigeprogramm versagt

        Erzeuge mal nur die HTML-Datei mit den kodierten Graphiken, lege diese lokal ab und sieh dir diese im Browser an. Danach versende die selbe Datei als Mail und sieh Dir das Ergebnis an.

        Wenn es also immer noch kaputte Mailclients gibt, welche nur vormachen, HTML zu verstehen, dann bleibt nur Roberts Vorschlag:

        Du möchtest dich eventuell mit Attachments und Content ID in dem Zusammenhang beschäftigen. Kurz gesagt werden die Bilder Anhänge der Email und können über das Pseudo-Protokoll cid refereniert werden – auch mehrfach.

        Du hängst die Original-Graphik an, versiehst diese mit einer eindeutigen Content-ID (am besten eine UUID im Subheader und referenzierst die Grafik im HTML mit selbiger.

        Schau Dir dazu einfach HTML-Mails mit solchen Graphiken mal im Quelltext an, das ist ziemlich simpel.

        1. Hallo Sorry, das ich mich erst jetzt wieder melde.

          Ich habe das Problem lösen können. Es funktioniert nun so wie ich es möchte.

          Ich hatte folgenden Ablauf. Ich habe die JPG-Daten unter : https://webtool.yah101.com/de/e_d/Base64_Encode_Image Konvertiert.

          Ich habe dann meine Email in die Zwischenablage geschrieben und wieder dekodiert. Auch das klappe, das Bild wurde angezeigt. Einen Fehlerhaften Code bei meiner Programmierung konnte ich somit ausschließen. Leider war Outlook 2016 nicht in der Lage das Bild anzuzeigen.

          Der Fehler lag daran, dass bei Konvertieren ein Leerzeichen zwischen Data: und image geschrieben wurde. Nicht bei mir sondern bei der Kodierung. Das dekodieren mit Leeerzeichen funktioniert auch auf der Seite. Nur nicht bei Outlook 2016.

          data: image/jpeg;base64 musste zu data:image/jpeg;base64 gewandelt werden und es klappt.

          Danke für die Hilfe. Martin

          1. Lieber Namensvetter,

            Der Fehler lag daran, dass bei Konvertieren ein Leerzeichen zwischen Data: und image geschrieben wurde. Nicht bei mir sondern bei der Kodierung. Das dekodieren mit Leeerzeichen funktioniert auch auf der Seite. Nur nicht bei Outlook 2016.

            data: image/jpeg;base64 musste zu data:image/jpeg;base64 gewandelt werden und es klappt.

            ja, das ergibt Sinn. Auch bei Webadressen darf ja nach dem Doppelpunkt von http: oder https: kein Blank stehen. Eigentlich klar, aber man muss so einen blöden Fehler erstmal wahrnehmen.

            Mich wundert allerdings, dass das Online-Tool einen solchen Fehler erzeugt.

            Einen schönen Tag noch
             Martin

            --
            "Haben Sie meinen Hund gerade dämlich genannt? Unerhört!! Mein Hund ist intelligenter als ich!"
            1. Hallo

              Ich muss noch mal mit einem Problem zurückkommen.

              Der Versand und das Anzeigen in Outlook 2016 klappt super.

              Auf dem Handy werden die 2 Bilder nicht angezeigt. Die Darstellung, wo das Bild sein sollte, ist auch unterschiedlich.

              Ich füge beide Bilder man an. Gibt es einen Code den ich für Handyansichten noch erfassen muss? oder was könnte das Problem sein? Das erste Bild hat einer Größe von 150KB das zweite Bilde 59KB.

              Danke Martin

              1. Gibt es einen Code den ich für Handyansichten noch erfassen muss?

                Leg mal den vollständigen Quelltext des versendeten Mails (exportieren als eml-Datei, dann umbenennen, mit der Endung „txt“) irgendwo ab (im Web, für uns abrufbar. So wie das Bildschirmfoto aussieht versendest Du wahrscheinlich ein Mail, welches von manchen Programmen „spekulativ repariert“ wird, (Microsoft kennt seine Benutzer und seinen eigenen Outlook-Schrott...) von anderen (deren Autoren sich beim Spekulieren nicht irren wollen) eben nicht. Womöglich fehlt die Angabe für den Content-Typ, womöglich noch mehr.

                Bei HTML-Mails muss es einen Text-Part geben (der, das ist ganz böse, leer sein kann → das führt zu Punkten beim Spam-Scoring) und einen HTML-Part, der quasi als Anhang verschickt wird:

                #### Weitere Header ###
                MIME-Version: 1.0
                Content-Type: multipart/mixed; 
                	boundary="----=_Part_2344014_1173900415.1675849059881"
                
                ------=_Part_2344014_1173900415.1675849059881
                Content-Type: text/html;charset=UTF-8
                Content-Transfer-Encoding: quoted-printable
                
                <!DOCTYPE html>
                <html lang="de">
                #Das Gelörre
                </html>
                ------=_Part_2344014_1173900415.1675849059881--
                

                Die Trennzeilen erstelle mit etwas wie

                $PartID        = microtime( true ) . '.' . random_int(0, PHP_INT_MAX );
                $StartBoundary = '------=_Part_' . $PartID;
                $EndBoundary   = $StartBoundary . '--';
                

                Da für den HTML-Part die Kodierung quoted-printable vorgesehen ist, muss der HTML-Part durch quoted_printable_encode() gejagt werden.

                Also

                $htmlpart = $StartBoundary
                            . "\r\n"
                            . quoted_printable_encode($html)
                            . "\r\n"
                            . $EndBoundary;
                
                

                Oder Du nimmst etwas wie den PHP-Mailer, der kümmert sich für Dich um das ganze Geraffel. (Sieh dort bei „A Simple Example“ nach…, baue aber ordentliches HTML)

                1. Hallo

                  Ich erstelle die Email in meinem Programm und übergebe dann die Daten an eine DLL von outlook.

                  Meinen Emailtext habe ich hier gespeichert. https://www.bs-tastatur.de/email.txt Dort müsste er abrufbar sein.

                  Meine Internetkopfzeilen aus Outlook

                  Return-Path: <bstastatur@gmail.com>
                  Received: from PCMartin (p578a9728.dip0.t-ipconnect.de. [87.138.151.40])
                          by smtp.gmail.com with ESMTPSA id d3-20020a056000114300b002c3f9404c45sm2346701wrx.7.2023.02.08.04.22.18
                          for <bstastatur@gmail.com>
                          (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);
                          Wed, 08 Feb 2023 04:22:19 -0800 (PST)
                  From: <bstastatur@gmail.com>
                  To: <bstastatur@gmail.com>
                  Subject: Testmail
                  Date: Wed, 8 Feb 2023 13:16:15 +0100
                  Message-ID: <047701d93bb7$24e4d210$6eae7630$@gmail.com>
                  MIME-Version: 1.0
                  Content-Type: multipart/mixed;
                  	boundary="----=_NextPart_000_0478_01D93BBF.86B37340"
                  X-Mailer: Microsoft Outlook 16.0
                  Thread-Index: Adk7tyPsGSudZ3iyRJi+Jil+7bRNQw==
                  Content-Language: de
                  X-Antivirus: Avast (VPS 230207-6, 7.2.2023), Outbound message
                  X-Antivirus-Status: Clean
                  X-Antivirus: Avast (VPS 230207-6, 7.2.2023), Inbound message
                  X-Antivirus-Status: Clean
                  X-Antivirus: avast! (VPS 230207-6, 07.02.2023), Inbound message
                  X-Antivirus-Status: Clean
                  

                  Vielleicht hilft das weiter. Martin

                  1. und übergebe dann die Daten an eine DLL von outlook.

                    Wer (BITTE!) macht denn SOWAS?

                    Vielleicht hilft das weiter. Martin

                    Nein. Leider gar nicht. Ich sehe nicht, ob und wie das HTML-Zeug für den Transport kodiert wurde. Ich sehe auch nicht (und bezweifle im Hinblick auf die gezeigten Ergebnisse) das der HTML-Part korrekt eingebunden wurde. Das sieht man in Deinem Fall wohl erst nach dem Empfang. Und zwar in den Headern des Emails.

                    Und da ich über „eine DLL von outlook“ nichts weiß kann ich nur vermuten, dass es dazu doch irgendeine Dokumentation geben müsste. Vielleicht fragst Du besser in einem MS-Office- oder VBA-Forum nach, wie man mit der besagten „DLL von outlook“ HTML-Mails versendet.

                    HINT: Mit PHP oder Python (nichts von beiden braucht einen Webserver, die laufen auch allein) wäre ich längst fertig…

                    1. Wer (BITTE!) macht denn SOWAS?

                      Das ist ganz einfach. Eine eigene Software die über viele Jahre gewachsen ist. Ich programmiere seit 1996 damit. Läuft auf 64 Bit und ich kann auf meinen gesamten Datenbestand zugreifen. Meine Funktionalität die ich habe kann ich woanders nicht kaufen oder müsste 1000ende von € ausgeben. Der Nachfolger ist X# und immer noch aktuell.

                      Ich schau mal in den "Visual Object" Foren ob ich was finde. VO hat auch eine eigene Email-Klasse. Mit der habe ich mich aber noch nicht beschäftigt. Dort gibt es auch Funktionen um den Header zu setzen.

                      Danke erst einmal für deine Hilfe.

                      Martin

                      1. Hallo tudorf,

                        wow, Visual Objects gibt's immer noch und es wird sogar auf .net übertragen? In den 80er/90ern habe ich auch xBase programmiert, da aber mit dem Clipper Compiler. VO haben wir uns angeschaut, es schien aber auf damaliger Hardware komplett unbrauchbar zu sein (viel zu langsam) und es hatte mit klassischem xBase/DOS gar nichts mehr zu tun. Es war also keine Option, mit der wir unsere Investitionen hätten retten können.

                        Wenn Du eine Ausführungsumgebung hast, in der Du COM Objekte nutzen kannst (deine Outlook-DLL wird sicherlich das Outlook COM Objekt sein), dann ist das auf jeden Fall eine valide Vorgehensweise. Man muss nicht immer direkt mit dem Mailserver reden.

                        Wir hier bei Selfhtml sind mit solchen Systemen eher weniger vertraut, bei uns geht's eher um Webserver und HTML-Seiten. Daher Raketenwillis Reaktion.

                        Rolf

                        --
                        sumpsi - posui - obstruxi
                        1. Daher Raketenwillis Reaktion.

                          Naja. Microsofts Outlook hat ein paar Besonderheiten, die ich mal als „mutigen Umgang mit den Normen“ beschreibe.

                          Nur denken die Outlook-Benutzer immer, das ihr hochwertes Programm richtig funktioniert. Was aber nicht stimmt, wie ich erfahren musste als ich anno dazumal (England hatte eine Königin und die gebrauchte noch höchstselbst das Schwert gegen William Gates) aber immerhin schon in diesem Jahrtausend, Mails (übrigens mit Anhängen und natürlich mit PHP...) via POP3 vom Server abgeholt und in (m)ein Ticket-System eingelesen habe.

                          Wie auch immer DAS sei, ich würde nicht erwarten, dass ein per „DLL von Outlook“ gesendetes Mail beim Empfänger korrekt (im Sinne von „wie erwartet“) dargestellt wird... Deshalb das „Wer (BITTE!) macht denn SOWAS?“.

                          1. Hi,

                            Nur denken die Outlook-Benutzer immer, das ihr hochwertes Programm richtig funktioniert.

                            ja, aber das ist leider nicht so. Outlook kann viel - ein bisschen e-Mail (das ist wohl die bekannteste Funktion), ein bisschen Terminkalender, ein bisschen Aufgabenplaner. Aber nichts von alledem wirklich gut.

                            Wie auch immer DAS sei, ich würde nicht erwarten, dass ein per „DLL von Outlook“ gesendetes Mail beim Empfänger korrekt (im Sinne von „wie erwartet“) dargestellt wird...

                            Ich auch nicht. Bestenfalls innerhalb eines reinen Microsoft-Ökosystems.

                            Einen schönen Tag noch
                             Martin

                            --
                            "Haben Sie meinen Hund gerade dämlich genannt? Unerhört!! Mein Hund ist intelligenter als ich!"
                  2. Oh. Mein. Gott. Ich hab das lange nicht mehr so gemacht... (seit ich den PHP-Mailer kenne und deshalb das Schreiben einer eigenen Libary abgebrochen habe)

                    `Return-Path: <bstastatur@gmail.com>
                    Received: from PCMartin (p578a9728.dip0.t-ipconnect.de. [87.138.151.40])
                            by smtp.gmail.com with ESMTPSA id d3-20020a056000114300b002c3f9404c45sm2346701wrx.7.2023.02.08.04.22.18
                            for <bstastatur@gmail.com>
                            (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);
                            Wed, 08 Feb 2023 04:22:19 -0800 (PST)
                    From: <bstastatur@gmail.com>
                    To: <bstastatur@gmail.com>
                    Subject: Testmail
                    Date: Wed, 8 Feb 2023 13:16:15 +0100
                    Message-ID: <047701d93bb7$24e4d210$6eae7630$@gmail.com>
                    MIME-Version: 1.0
                    Content-Type: multipart/mixed;
                    	boundary="----=_NextPart_000_0478_01D93BBF.86B37340"
                    # Geraffel
                    

                    Ja. Es hilft tatsächlich - weil ich nun sehe, was fehlt.

                    Nämlich genau das, was ich oben aufgeführt habe. Generell ist das erzeugte Mail also „kaputt“. Du musst in der Dok zu Deiner Outlook-DLL suchen, wie man

                    • den oder die Empfänger (auch CC, BCC)
                    • den Absender, den oder die Empfänger der Antwort
                    • das Subjekt
                    • die Ankündigung des Multipart-Teils
                    • die Ankündigung des Mixed-Teils
                    • den Text-Teil
                    • den HTML-Teil (wegen dieser Teile heisst es ja "multipart/mixed")
                    • die Ankündigung der übrigen Anhänge
                    • die übrigen Anhänge selbst beifügt.

                    Bei einem Content-Type: multipart/mixed; schließt sich als nächstes ein Plain-Text-Teil an (mit entsprechendem Header).

                    Wenn man ein KORREKTES Mail mit Text, HTML und Anhängen „von Hand“ machen will..., dann sieht das im Kern so aus:

                    Content-Type: multipart/mixed; boundary="Boundary_AAAAA"
                    -- Boundary_AAAAA"
                    
                    Content-Type: multipart/alternative; boundary="Boundary_BBBBB"
                    
                    --Boundary_BBBBB
                    Content-Type: text/plain;charset=UTF-8
                    Content-Transfer-Encoding: quoted-printable
                    
                    Hier die Nachricht im Text-Format für Mailempfänger,
                    welche kein HTML empfangen oder darstellen können
                    oder das bewusst nicht wollen...
                    
                    --Boundary_BBBBB
                    Content-Type: text/html;charset=UTF-8
                    Content-Transfer-Encoding: quoted-printable
                    
                    <!doctype html>
                    <html dir="ltr" lang="de">
                    <h1>Hier die Nachricht im HTML-Format.</h1>
                    <p>Denke aber an das quoted-printable
                    </html>
                    
                    
                    --Boundary_BBBBB--
                    --Boundary_AAAAA
                    Content-Type: application/octet-stream; name=Datei-1.pdf
                    Content-Transfer-Encoding: base64
                    Content-Disposition: attachment; filename=Datei-1.pdf
                    
                    JVBERi0xLjMNCiXi48/TDQo2IDAgb2JqDQo8PA0KL1R5cGUgL1BhZ2UNCi9QYXJlbnQgMiAwIFIN
                    YWI+XQ0KPj4NCnN0YXJ0eHJlZg0KMjU2NDE5DQolJUVPRg==
                    
                    --Boundary_AAAAA
                    Content-Type: application/octet-stream; name=Datei-2.pdf
                    Content-Transfer-Encoding: base64
                    Content-Disposition: attachment; filename=Datei-2.pdf
                    
                    JVBERi0xLjMNCiXi48/TDQo2IDAgb2JqDQo8PA0KL1R5cGUgL1BhZ2UNCi9QYXJlbnQgMiAwIFIN
                    YWI+XQ0KPj4NCnN0YXJ0eHJlZg0KMjU2NDE5DQolJUVPRg==
                    --Boundary_AAAAA--
                    

                    Hinweis: Ich habe oben natürlich weder das HTML noch den Text gequotet. Du musst das aber tun- übrigens auch Subjekt und ggf. Namen bei den Adressen (from, to. replto, cc, bcc)

                    • Beachte die "-"-Symbole vor und nach den Boundary.
                    • Beachte deren Verschachtelung
                    • Beachte, dass der Boundary strikt unique sein muss. Üblich ist ein Konstrukt aus Zeit (Mikrosekunden) und großer Zufallszahl. Sonst bekommt der Empfänger, besonders wenn sein Programm alle Mails in einer Datei speichert, recht herzliche Probleme!

                    Im Prinzip hat das Mail, welches Du senden willst, folgenden Aufbau (ich lehne mich mal an Javascript bzw. PHP an um die Verschachtelung zu zeigen.

                    Mail {
                        Mailheader {
                           ....
                    
                        }
                        Multipart Mixed {
                           Multipart Alternative {
                               Text-Part {
                                  header { }
                                  Nutzlast { }
                               }
                               HTML-Part {
                                  header { }
                                  Nutzlast { }
                               }
                           }
                       }
                       Anhang 1 {
                           header { }
                           Nutzlast { }
                       }
                       ...
                       Anhang N {
                           header { }
                           Nutzlast { }
                       }
                    }
                    
                    • Jede Ebene (Einzugstiefe) braucht hierbei einen eigenen Boudary!

                    • Außerdem kannst Du, weil in Mails nur ASCII erlaubt ist, auch das HTML mit base64 kodieren, musst das dann aber angeben.

                    • Und noch etwas: in Mails dürfen Zeilen keine 1000 Zeichen lang sein. Üblich ist es, diese nach 77 Zeichen umzubrechen. Das betrifft insbesondere die bas64-kodierten Teile, die müssen nach der Kodierung noch umgebrochen werden, beim Dekodieren muss das empfangende Programm dann nichts machen, weil alle (mir bekannten) Base64-Dekodierer Zeilenumbrüche im Input ignorieren, weil die ja kodiert sind.

                    • Und vermeide, wenn Du quoted-printable verwendest, in der Nutzlast Zeilen, die nur aus einem Punkt bestehen. Das signalisiert das Ende des Mails...

                    Literatur:

                    https://www.rfc-editor.org/rfc/rfc5322 (Als Beginn)

                    1. Hallo,

                      • Außerdem kannst Du, weil in Mails nur ASCII erlaubt ist, auch das HTML mit base64 kodieren, musst das dann aber angeben.

                      ja, aber ich würde, zumindest in westlichen Sprachen, deren Schriftform überwiegend in ASCII darstellbar ist, doch eher zu Quoted-Printable raten. Der Lesbarkeint auch im Quellcode zuliebe.

                      weil in Mails nur ASCII erlaubt ist

                      Das stimmt so nicht ganz. Mit Content-Transfer-Encoding: 8bit darf man sich gern über diese Beschränkung hinwegsetzen. Die Zahl der Systeme, die das nicht kennen und unterstützen, dürfte heutzutage gegen Null gehen.

                      Einen schönen Tag noch
                       Martin

                      --
                      "Haben Sie meinen Hund gerade dämlich genannt? Unerhört!! Mein Hund ist intelligenter als ich!"