web-dev-qa-db-fra.com

image incorporée dans un courriel html

J'essaie d'envoyer un email multipart/related HTML avec des images GIF intégrées. Cet email est généré avec Oracle PL/SQL. Mes tentatives ont échoué. L'image apparaît sous la forme d'un X rouge (dans Outlook 2007 et Yahoo Mail).

J'envoie des emails en HTML depuis un certain temps, mais je dois maintenant utiliser plusieurs images gif dans l'email. Je peux les stocker sur l'un de nos serveurs Web et y créer des liens, mais de nombreux clients de messagerie ne les montreront pas automatiquement et devront modifier les paramètres ou les télécharger manuellement pour chaque email.

Donc, mes pensées sont d'intégrer l'image. Mes questions sont:

  1. Qu'est-ce que je fais mal ici?
  2. L'approche d'intégration est-elle la bonne?
  3. Y a-t-il d'autres options si j'ai besoin d'utiliser de plus en plus d'images? Les pièces jointes ne fonctionneront pas, car les images sont généralement des logos et des icônes qui n'ont pas de sens en dehors du contexte du message. De plus, certains éléments de l'e-mail sont des liens vers un système en ligne. Par conséquent, générer un fichier statique PDF et le joindre ne fonctionneront pas (à ma connaissance, de toute façon).

fragment:

MIME-Version: 1.0
To: [email protected]
BCC: [email protected]
From: [email protected]
Subject: Test
Reply-To: [email protected]
Content-Type: multipart/related; boundary="a1b2c3d4e3f2g1"

--a1b2c3d4e3f2g1

content-type: text/html;

    <html>
    <head><title>My title</title></head>
    <body>
    <div style="font-size:11pt;font-family:Calibri;">
    <p><IMG SRC="cid:my_logo" alt="Logo"></p>

... more html here ...

</div></body></html> 

--a1b2c3d4e3f2g1

Content-Type: image/gif;
Content-ID:<my_logo>
Content-Transfer-Encoding: base64
Content-Disposition: inline

[base64 image data here]

--a1b2c3d4e3f2g1--

Merci beaucoup.

BTW: Oui, j'ai vérifié que les données base64 sont correctes, car je peux incorporer l'image dans le code HTML lui-même (en utilisant le même usage que pour créer des données d'en-tête) et voir l'image dans Firefox/IE.

Je devrais également noter que ce n'est pas pour le spam, les emails sont envoyés à des clients spécifiques qui l'attendent tous les jours. Le contenu est basé sur les données et non sur les publicités.

85
tbone

Essayez de l'insérer directement, de cette manière, vous pourrez insérer plusieurs images à différents endroits du courrier électronique.

<img src="data:image/jpg;base64,{{base64-data-string here}}" />

Et pour que ce message soit utile aux autres: Si vous n'avez pas de chaîne base64-data, créez-en une facilement à l'adresse: http://www.motobit.com/util/base64-decoder -encoder.asp à partir d'un fichier image.

Le code source de l'e-mail ressemble à ceci, mais je ne peux vraiment pas vous dire à quoi sert cette limite:

 To: [email protected]
 Subject: ...
 Content-Type: multipart/related;
 boundary="------------090303020209010600070908"

This is a multi-part message in MIME format.
--------------090303020209010600070908
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-15">
  </head>
  <body bgcolor="#ffffff" text="#000000">
    <img src="cid:part1.06090408.01060107" alt="">
  </body>
</html>

--------------090303020209010600070908
Content-Type: image/png;
 name="moz-screenshot.png"
Content-Transfer-Encoding: base64
Content-ID: <part1.06090408.01060107>
Content-Disposition: inline;
 filename="moz-screenshot.png"

[base64 image data here]

--------------090303020209010600070908--

// EDIT: Oh, je viens de me rendre compte que si vous insérez le premier extrait de code de mon message pour écrire un courrier électronique avec Thunderbird, Thunderbird modifie automatiquement le code html afin qu'il ressemble beaucoup au deuxième code de mon message.

114
Bernd

L’autre solution consiste à joindre l’image en pièce jointe, puis à la référencer en utilisant le code HTML à l’aide de cid.

Code HTML:

<html>
    <head>
    </head>
    <body>
        <img width=100 height=100 id=""1"" src=""cid:Logo.jpg"">
    </body>
</html>

Code C #:

EmailMessage email = new EmailMessage(service);
email.Subject = "Email with Image";
email.Body = new MessageBody(BodyType.HTML, html);
email.ToRecipients.Add("[email protected]");
string file = @"C:\Users\acv\Pictures\Logo.jpg";
email.Attachments.AddFileAttachment("Logo.jpg", file);
email.Attachments[0].IsInline = true;
email.Attachments(0).ContentId = "Logo.jpg";
email.SendAndSaveCopy();
14
Khyati Elhance

Je ne trouve aucune des réponses utiles ici, alors je propose ma solution.

  1. Le problème est que vous utilisez multipart/related comme type de contenu, ce qui n’est pas approprié dans ce cas. J'utilise multipart/mixed et à l'intérieur multipart/alternative (cela fonctionne sur la plupart des clients).

  2. La structure du message devrait être la suivante: 

    [Headers]
    Content-type:multipart/mixed; boundary="boundary1"
    --boundary1
    Content-type:multipart/alternative; boundary="boundary2"
    --boundary2
    Content-Type: text/html; charset=ISO-8859-15
    Content-Transfer-Encoding: 7bit
    [HTML code with a href="cid:..."]
    
    --boundary2
    Content-Type: image/png;
    name="moz-screenshot.png"
    Content-Transfer-Encoding: base64
    Content-ID: <part1.06090408.01060107>
    Content-Disposition: inline; filename="moz-screenshot.png"
    [base64 image data here]
    
    --boundary2--
    --boundary1--
    

Alors ça va marcher 

9
Pavel Perna

Si cela ne fonctionne pas, vous pouvez essayer l'un de ces outils qui convertissent l'image en un tableau HTML (attention à la taille de votre image):

6
Erwin Mayer

Utiliser Base64 pour incorporer des images au format HTML est génial. Néanmoins, veuillez noter que les chaînes base64 peuvent rendre votre email plus gros. 

Donc, 

1) Si vous avez plusieurs images, le téléchargement de vos images sur un serveur et leur chargement à partir du serveur peuvent réduire la taille de votre courrier électronique. (Vous pouvez obtenir beaucoup de services gratuits via Google)

2) S'il n'y a que quelques images dans votre courrier, utiliser des chaînes base64 est vraiment une option géniale.

Outre les choix fournis par les réponses existantes, vous pouvez également utiliser une commande pour générer une chaîne base64 sur linux:

base64 test.jpg
4
Brian
  1. Vous devez disposer de trois limites pour que les images en ligne soient totalement conformes.

  2. Tout se passe dans le multipart/mixed.

  3. Utilisez ensuite le multipart/related pour contenir votre multipart/alternative et vos en-têtes de pièce jointe.

  4. Enfin, incluez vos pièces jointes téléchargeables dans la dernière limite de multipart/mixed.

1
Steven Newman

Il existe en fait un très bon article de blog qui répertorie les avantages et les inconvénients de trois approches différentes de ce problème par Martyn Davies. Vous pouvez le lire à https://sendgrid.com/blog/embedding-images-emails-facts/ .

J'aimerais ajouter une quatrième approche utilisant des images de fond CSS.

Ajouter

<div id="myImage"></div>

à votre corps d'e-mail et à une classe css comme:

#myImage {
    background-image:  url('data:image/png;base64,iVBOR...[some more encoding]...rkggg==');
    width: [the-actual-image-width];
    height: [the-actual-image-height];
}
1
GerardV

Il peut être intéressant qu'Outlook et Outlook Express puissent générer ces formats de courrier électronique en plusieurs parties si vous insérez les fichiers image à l'aide de la fonction de menu Insérer/Image.

De toute évidence, le type de courrier électronique doit être défini sur HTML (pas de texte brut).

Toute autre méthode (par exemple, glisser-déposer ou appel de ligne de commande) entraîne l'envoi de la ou des images en tant que pièce jointe.

Si vous envoyez ensuite un tel courriel à vous-même, vous pouvez voir comment il est formaté! :)

FWIW, je suis à la recherche d’un exécutable autonome pour Windows qui effectue des images en ligne à partir du mode ligne de commande, mais il semble qu’il n’en existe aucune. C'est un chemin que beaucoup ont emprunté ... On peut le faire avec, disons, Outlook Express, en lui transmettant un fichier .eml correctement formaté.

1
Peter

Je sais que ceci est un ancien message, mais les réponses actuelles ne traitent pas du fait qu'Outlook et de nombreux autres fournisseurs de messagerie ne prennent pas en charge les images en ligne ou les images CID. Le moyen le plus efficace de placer des images dans des courriers électroniques consiste à l'héberger en ligne et à placer un lien vers celle-ci dans le courrier électronique. Pour les petites listes de courrier électronique, une boîte de dépôt publique fonctionne bien. Cela réduit également la taille de l'e-mail.

1
Scooter Crawford

Ce qui suit est un code de travail avec deux manières d'y parvenir:

using System;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {

            Method1();
            Method2();
        }

        public static void Method1()
        {
            Outlook.Application outlookApp = new Outlook.Application();
            Outlook.MailItem mailItem = outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
            mailItem.Subject = "This is the subject";
            mailItem.To = "[email protected]";
            string imageSrc = "D:\\Temp\\test.jpg"; // Change path as needed

            var attachments = mailItem.Attachments;
            var attachment = attachments.Add(imageSrc);
            attachment.PropertyAccessor.SetProperty("http://schemas.Microsoft.com/mapi/proptag/0x370E001F", "image/jpeg");
            attachment.PropertyAccessor.SetProperty("http://schemas.Microsoft.com/mapi/proptag/0x3712001F", "myident"); // Image identifier found in the HTML code right after cid. Can be anything.
            mailItem.PropertyAccessor.SetProperty("http://schemas.Microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8514000B", true);

            // Set body format to HTML

            mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
            string msgHTMLBody = "<html><head></head><body>Hello,<br><br>This is a working example of embedding an image unsing C#:<br><br><img align=\"baseline\" border=\"1\" hspace=\"0\" src=\"cid:myident\" width=\"\" 600=\"\" hold=\" /> \"></img><br><br>Regards,<br>Tarik Hoshan</body></html>";
            mailItem.HTMLBody = msgHTMLBody;
            mailItem.Send();
        }

        public static void Method2()
        {

            // Create the Outlook application.
            Outlook.Application outlookApp = new Outlook.Application();

            Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);

            //Add an attachment.
            String attachmentDisplayName = "MyAttachment";

            // Attach the file to be embedded
            string imageSrc = "D:\\Temp\\test.jpg"; // Change path as needed

            Outlook.Attachment oAttach = mailItem.Attachments.Add(imageSrc, Outlook.OlAttachmentType.olByValue, null, attachmentDisplayName);

            mailItem.Subject = "Sending an embedded image";

            string imageContentid = "someimage.jpg"; // Content ID can be anything. It is referenced in the HTML body

            oAttach.PropertyAccessor.SetProperty("http://schemas.Microsoft.com/mapi/proptag/0x3712001E", imageContentid);

            mailItem.HTMLBody = String.Format(
                "<body>Hello,<br><br>This is an example of an embedded image:<br><br><img src=\"cid:{0}\"><br><br>Regards,<br>Tarik</body>",
                imageContentid);

            // Add recipient
            Outlook.Recipient recipient = mailItem.Recipients.Add("[email protected]");
            recipient.Resolve();

            // Send.
            mailItem.Send();
        }
    }
}
0
Tarik

Pour ceux qui ne pouvaient pas utiliser l’une de ces solutions: Envoyer une image inline par courrier électronique En suivant les étapes décrites dans la solution proposée par @ T30, j’ai pu afficher mon image inline sans être bloqué par Outlook (méthodes précédentes, il était bloqué). Si vous utilisez l’échange comme nous le faisons alors également: 

service = new ExchangeService(ExchangeVersion);
service.AutodiscoverUrl("[email protected]");
SmtpClient smtp = new SmtpClient(service.Url.Host);

vous devrez lui transmettre votre hôte de service d'échange. En dehors de cela, cette solution devrait vous permettre d’envoyer facilement des images intégrées.

0
tstrand66