Gmail 阻止电子邮件模板中嵌入的小型嵌入式图像

Posted

技术标签:

【中文标题】Gmail 阻止电子邮件模板中嵌入的小型嵌入式图像【英文标题】:Gmail blocking small embedded inline images in email template 【发布时间】:2017-06-16 06:03:21 【问题描述】:

我正在向我的成员发送电子邮件,但 Gmail 似乎阻止了我在电子邮件中放置的图像。这些作为 base 64 编码 字符串嵌入到 img 标记中。我在网上查看了多个关于 Gmail 不发送图片的帖子,但没有发现任何有用的信息。 以下是我迄今为止尝试过的一些事情。 1. 在 Gmail 中启用外部图片(通过设置图标) 2. 将图片大小减少到 8000 字节以下(Outlook.com 不会发送图片 ~ 15000 字节)

如果我发送到 Outlook.com 电子邮件地址,我会收到图片,但在 Gmail 中,img 标签的 src 为空,并且电子邮件中不显示任何图片。 我正在使用 https://putsmail.com 测试/发送我的电子邮件,所以我知道问题不是 SendGrid(我的电子邮件发送服务)或我的应用程序的问题。

这是我的以下模板之一。我正在使用来自 litmuss 的电子邮件模板。下面的所有内容基本上都是默认的,除了我添加的额外信息,比如图像和电子邮件正文中的一些额外文本。

这是一个jsfiddle,带有一个完整的模板,其中包含可以直接复制到 putsmail 并发送到测试的图像数据!任何有关 Gmail 为何不发送图片的帮助或信息都会很棒!

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <style type="text/css">
        /* FONTS */
        @@media screen 
            @@font-face 
                font-family: 'Lato';
                font-style: normal;
                font-weight: 400;
                src: local('Lato Regular'), local('Lato-Regular'), url(https://fonts.gstatic.com/s/lato/v11/qIIYRU-oROkIk8vfvxw6QvesZW2xOQ-xsNqO47m55DA.woff) format('woff');
            

            @@font-face 
                font-family: 'Lato';
                font-style: normal;
                font-weight: 700;
                src: local('Lato Bold'), local('Lato-Bold'), url(https://fonts.gstatic.com/s/lato/v11/qdgUG4U09HnJwhYI-uK18wLUuEpTyoUstqEm5AMlJo4.woff) format('woff');
            

            @@font-face 
                font-family: 'Lato';
                font-style: italic;
                font-weight: 400;
                src: local('Lato Italic'), local('Lato-Italic'), url(https://fonts.gstatic.com/s/lato/v11/RYyZNoeFgb0l7W3Vu1aSWOvvDin1pK8aKteLpeZ5c0A.woff) format('woff');
            

            @@font-face 
                font-family: 'Lato';
                font-style: italic;
                font-weight: 700;
                src: local('Lato Bold Italic'), local('Lato-BoldItalic'), url(https://fonts.gstatic.com/s/lato/v11/HkF_qI1x_noxlxhrhMQYELO3LdcAZYWl9Si6vvxL-qU.woff) format('woff');
            
        

        /* CLIENT-SPECIFIC STYLES */
        body, table, td, a 
            -webkit-text-size-adjust: 100%;
            -ms-text-size-adjust: 100%;
        

        table, td 
            mso-table-lspace: 0pt;
            mso-table-rspace: 0pt;
        

        img 
            -ms-interpolation-mode: bicubic;
        

        /* RESET STYLES */
        img 
            border: 0;
            height: auto;
            line-height: 100%;
            outline: none;
            text-decoration: none;
        

        table 
            border-collapse: collapse !important;
        

        body 
            height: 100% !important;
            margin: 0 !important;
            padding: 0 !important;
            width: 100% !important;
        

        /* ios BLUE LINKS */
        a[x-apple-data-detectors] 
            color: inherit !important;
            text-decoration: none !important;
            font-size: inherit !important;
            font-family: inherit !important;
            font-weight: inherit !important;
            line-height: inherit !important;
        

        /* MOBILE STYLES */
        @@media screen and (max-width:600px) 
            h1 
                font-size: 32px !important;
                line-height: 32px !important;
            
        

        /* android CENTER FIX */
        div[style*="margin: 16px 0;"] 
            margin: 0 !important;
        
    </style>
</head>
<body style="background-color: #f4f4f4; margin: 0 !important; padding: 0 !important;">

    <!-- HIDDEN PREHEADER TEXT -->
    <div style="display: none; font-size: 1px; color: #fefefe; line-height: 1px; font-family: 'Lato', Helvetica, Arial, sans-serif; max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden;">
        We're thrilled you created a YogaBandy event! Get ready for members to register.
    </div>

    <table border="0" cellpadding="0" cellspacing="0" >
        <!-- LOGO -->
        <tr>
            <td bgcolor="#16749F" align="center">
                <!--[if (gte mso 9)|(IE)]>
                <table align="center" border="0" cellspacing="0" cellpadding="0" >
                <tr>
                <td align="center" valign="top" >
                <![endif]-->
                <table border="0" cellpadding="0" cellspacing="0"  style="max-width: 600px;">
                    <tr>
                        <td align="center" valign="top" style="padding: 40px 10px 40px 10px;">
                            <a href="https://YogaBandy.com" target="_blank">
                                <img  src="http://litmuswww.s3.amazonaws.com/community/template-gallery/ceej/logo.png"   style="display: block; width: 40px; max-width: 40px; min-width: 40px; font-family: 'Lato', Helvetica, Arial, sans-serif; color: #ffffff; font-size: 18px;" border="0">
                            </a>
                        </td>
                    </tr>
                </table>
                <!--[if (gte mso 9)|(IE)]>
                </td>
                </tr>
                </table>
                <![endif]-->
            </td>
        </tr>
        <!-- HERO -->
        <tr>
            <td bgcolor="#16749F" align="center" style="padding: 0px 10px 0px 10px;">
                <!--[if (gte mso 9)|(IE)]>
                <table align="center" border="0" cellspacing="0" cellpadding="0" >
                <tr>
                <td align="center" valign="top" >
                <![endif]-->
                <table border="0" cellpadding="0" cellspacing="0"  style="max-width: 600px;">
                    <tr>
                        <td bgcolor="#ffffff" align="center" valign="top" style="padding: 40px 20px 20px 20px; border-radius: 4px 4px 0px 0px; color: #111111; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 48px; font-weight: 400; letter-spacing: 4px; line-height: 48px;">
                            <h2 style="font-size: 48px; font-weight: 400; margin: 0;">Event Created</h2>
                        </td>
                    </tr>
                </table>
                <!--[if (gte mso 9)|(IE)]>
                </td>
                </tr>
                </table>
                <![endif]-->
            </td>
        </tr>
        <!-- COPY BLOCK -->
        <tr>
            <td bgcolor="#f4f4f4" align="center" style="padding: 0px 10px 0px 10px;">
                <!--[if (gte mso 9)|(IE)]>
                <table align="center" border="0" cellspacing="0" cellpadding="0" >
                <tr>
                <td align="center" valign="top" >
                <![endif]-->
                <table border="0" cellpadding="0" cellspacing="0"  style="max-width: 600px;">
                    <!-- COPY -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">We're excited you have created an event. Here are some of the details below.</p>
                        </td>
                    </tr>
                    <!-- Host Space -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">
                                <a href="https://www.YogaBandy.com/Space/Public/@Model.SpaceId" target="_blank" class="thumbnail" style="margin-bottom: 0px;">
                                    <img  title="Space Image" style="display: block"   src="data:image/jpg;base64,@Raw(Model.SpaceThumbnail)" />
                                    <div class="caption">
                                        @Model.SpaceName
                                    </div>
                                </a>
                            </p>
                        </td>
                    </tr>
                    <!-- Host Image -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">
                                <a href="https://www.YogaBandy.com/Profile/Public/@Model.HostId" target="_blank" class="thumbnail" style="margin-bottom: 0px;">
                                    <img  title="Host Image" style="display: block"   src="data:image/jpg;base64,@Raw(Model.HostThumbnail)" />
                                    <div class="caption">
                                        @Model.HostName
                                    </div>
                                </a>
                            </p>
                        </td>
                    </tr>
                    <!-- DATE -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">@Model.Date.ToLongDateString()</p>
                        </td>
                    </tr>
                    <!-- TIME -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">
                                <div>Time: @Model.Date.ToShortTimeString()</div>
                            </p>
                        </td>
                    </tr>
                    <!-- Location -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">@Model.Location</p>
                        </td>
                    </tr>
                    <!-- DURATION -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">@Model.Duration</p>
                        </td>
                    </tr>
                    <!-- STYLE -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">@Model.Style</p>
                        </td>
                    </tr>
                    <!-- BULLETPROOF BUTTON -->
                    <tr>
                        <td bgcolor="#ffffff" align="left">
                            <table  border="0" cellspacing="0" cellpadding="0">
                                <tr>
                                    <td bgcolor="#ffffff" align="center" style="padding: 20px 30px 60px 30px;">
                                        <table border="0" cellspacing="0" cellpadding="0">
                                            <tr>
                                                <td align="center" style="border-radius: 3px;" bgcolor="#16749F"><a href="" target="_blank" style="font-size: 20px; font-family: Helvetica, Arial, sans-serif; color: #ffffff; text-decoration: none; color: #ffffff; text-decoration: none; padding: 15px 25px; border-radius: 2px; border: 1px solid #16749F; display: inline-block;">Add To Calendar</a></td>
                                            </tr>
                                        </table>
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                    
                    
                    <!-- COPY -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 0px 30px 20px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">If you have any questions, just send an email to the support address—we're always happy to help out.</p>
                        </td>
                    </tr>
                    <!-- COPY -->
                    <tr>
                        <td bgcolor="#ffffff" align="left" style="padding: 0px 30px 40px 30px; border-radius: 0px 0px 4px 4px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <p style="margin: 0;">Cheers,<br>The YogaBandy Team</p>
                        </td>
                    </tr>
                </table>
                <!--[if (gte mso 9)|(IE)]>
                </td>
                </tr>
                </table>
                <![endif]-->
            </td>
        </tr>
        <!-- SUPPORT CALLOUT -->
        <tr>
            <td bgcolor="#f4f4f4" align="center" style="padding: 30px 10px 0px 10px;">
                <!--[if (gte mso 9)|(IE)]>
                <table align="center" border="0" cellspacing="0" cellpadding="0" >
                <tr>
                <td align="center" valign="top" >
                <![endif]-->
                <table border="0" cellpadding="0" cellspacing="0"  style="max-width: 600px;">
                    <!-- HEADLINE -->
                    <tr>
                        <td bgcolor="#157b9d" align="center" style="padding: 30px 30px 30px 30px; border-radius: 4px 4px 4px 4px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;">
                            <h2 style="font-size: 20px; font-weight: 400; color: #111111; margin: 0;">Need more help?</h2>
                            <p style="margin: 0;"><a href="https://YogaBandy/Contact.com" target="_blank" style="color: #FFFFFF;">We&rsquo;re here, ready to help</a></p>
                        </td>
                    </tr>
                </table>
                <!--[if (gte mso 9)|(IE)]>
                </td>
                </tr>
                </table>
                <![endif]-->
            </td>
        </tr>
        <!-- FOOTER -->
        <tr>
            <td bgcolor="#f4f4f4" align="center" style="padding: 0px 10px 0px 10px;">
                <!--[if (gte mso 9)|(IE)]>
                <table align="center" border="0" cellspacing="0" cellpadding="0" >
                <tr>
                <td align="center" valign="top" >
                <![endif]-->
                <table border="0" cellpadding="0" cellspacing="0"  style="max-width: 600px;">
                    <!-- NAVIGATION -->
                    <!-- PERMISSION REMINDER -->
                    <tr>
                        <td bgcolor="#f4f4f4" align="left" style="padding: 0px 30px 30px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: 400; line-height: 18px;">
                            <p style="margin: 0;">You received this email because you just created a YogaBandy event. If it looks weird, <a href="https://YogaBandy.com" target="_blank" style="color: #111111; font-weight: 700;">view it in your browser</a>.</p>
                        </td>
                    </tr>
                    <!-- UNSUBSCRIBE -->
                    <!-- ADDRESS -->

                </table>
                <!--[if (gte mso 9)|(IE)]>
                </td>
                </tr>
                </table>
                <![endif]-->
            </td>
        </tr>
    </table>

</body>
</html>

【问题讨论】:

相关:Inline image attachment on Gmail from GDrive - Web Applications Stack Exchange 如果您使用nodemailer,请查看解决方案here 【参考方案1】:

Google 拒绝在 Gmail 的网络界面中显示带有数据 URL 的图像。这是一个已知问题(在 Google 看来是一种安全措施),长期以来一直受到高度批评。

好消息是,除了使用外部图像之外,您还有其他选择。

使用带有 Content-ID 的内联附件适用于 Gmail。

将图片添加为内联附件后,您需要在 html 正文中指向 CID URLs 而不是 Data URLs。

有许多现代库可让您轻松发送带有内联附件的电子邮件。但是我用 CDO 库在 VBScript 中编写了一个示例脚本,如果您安装了 Windows 2000+ 的盒子,就可以使用了。

让我们准备测试环境。

将文件放在一个目录中,如下面的屏幕截图所示。

tpl.html 是你给的模板文件。您需要对此文件进行一些更改。

将两个img 元素分别替换为以下内容。请注意,数据网址消失了。 image1image2 是为脚本中的每个内联附件指定的内容 ID。此处没有与文件名相关的内容。

<img src="cid:image1"  title="Space Image" style="display: block"   />
<img src="cid:image2"  title="Host Image" style="display: block"   />

Embedded.vbs:

MsgBox "Wait while your email is being sent.", vbOKOnly Or vbInformation

'************ CONFIGURATION *************
Const smtpUsername = "..."
Const smtpPassword = "..."
Const smtpHost = "smtp.sendgrid.net"
Const smtpPort = 587
Const senderEmail = "...@..."
Const recipientEmail = "...@gmail.com"
'************ CONFIGURATION *************

Const cdoRefTypeId = 0

Set Fso = CreateObject("Scripting.FileSystemObject")

Set objMail = CreateObject("CDO.Message")
With objMail.Configuration
    .Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
    .Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = smtpUsername
    .Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = smtpPassword
    .Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = smtpHost
    .Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport")  = smtpPort
    .Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    .Fields("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 20 'secs
    .Fields.Update
End With

With objMail
    .AutoGenerateTextBody = False
    .From = senderEmail
    .To = recipientEmail
    .Subject = "Inline Image Test"
    .BodyPart.ContentTransferEncoding = "quoted-printable"
    .BodyPart.Charset = "utf-8"
    
    ' Adding images as inline attachments with Content IDs which is used with image sources. e.g. <img src="cid:image1" .. >
    .AddRelatedBodyPart Fso.GetAbsolutePathName("image1.jpg"), "image1", cdoRefTypeId
    .AddRelatedBodyPart Fso.GetAbsolutePathName("image2.jpg"), "image2", cdoRefTypeId
    
    'append html body from file
    .HTMLBody = Fso.OpenTextFile("tpl.html").ReadAll
    .Send
End With

MsgBox "Email successfully sent! Check your inbox.", vbOKOnly Or vbInformation

双击等待指示。

另见https://***.com/search?q=is%3Aquestion+%5Bemail%5D+inline+image

【讨论】:

感谢您添加对其他解决方案的引用。它帮助了很多!我最终找到了这个链接,它解决了我的问题:code.activestate.com/recipes/… 对于 Javax 邮件 api,请参阅 tutorialspoint.com/javamail_api/… 不能在 Windows 8 下工作。使用smtpPort=587The transport failed to connect to the server. 使用smtpPort=465The server rejected the sender address. The server response was: 530 5.7.0 Must issue a STARTTLS command first. @Brethlosze 所以您否决了这个答案,因为服务器拒绝您作为发件人发送的地址并且需要您未提供的 TLS?这个答案只不过是一个需要成功发送消息的概念证明。首先完成发送电子邮件,然后抱怨电子邮件中的图像是否不起作用。错误信息很清楚。如果您遇到这些错误,请随时提出新问题。【参考方案2】:

tl;dr

Gmail 和某些其他客户端不喜欢base64 编码图像。

全文

我做的第一件事是在 Gmail 中查看“显示原件”。令我惊讶的是,原始内容仍然包含您嵌入的图像数据:

这立即告诉我 gmail 只是选择过滤掉这些内容。我找不到原因。一些猜测指出了length of encoded data itself。其他人谈论Gmail filters out images的一般方式。甚至还有这种技术的记录functioning a number of years back。

此外,当在第三方客户端(例如 Newton(以前称为 Cloud Magic))中查看相同的电子邮件时,我确实看到了正确渲染的图像。

所有这些都指向一个简单但令人遗憾的事实,即 gmail 不喜欢内联编码的图像。不在浏览器中,也不在他们的移动应用中。

事实上,最后我确实发现了来自2013 by Campaign Monitor blog 的帖子,其结果相同。

不要使用内嵌图像。

【讨论】:

为了后代,众所周知Gmail doesn't support data-uri/data-url/embedded images。这与base64 编码、数据长度或Gmail 过滤内容的方式无关。据我所知,嵌入图像至少从 2010 年起就无法在 Gmail 中使用。您的答案的 TL;DR 仍然是正确的(不要使用内联图像),只是不希望未来的读者认为有办法让它与 Gmail 一起使用 - 据我所知,没有.【参考方案3】:

经过多次尝试和失败,我找到了 Gmail 不显示内嵌图片的原因。 原来我用的是这个html:

"Some HTML text and an image \<img src="cid:image1"\>Nifty!"

并附上此命令的图片(在python中,但细节不重要):

msg.add_related(img.read(), 'image', 'png', cid='image1')

它适用于大多数电子邮件客户端,但不适用于 Gmail android 应用程序和 Gmail 网络。 当我最终将其更改为:

 msg.add_related(img.read(), 'image', 'png', cid='\<image1\>')

它适用于 Outlook、Android 电子邮件、Android Gmail 和 Gmail 网络。 这个错误在很多 python 库的例子中重复出现。

【讨论】:

【参考方案4】:

你在用 nodemailer 吗?

如果是,有解决办法!

NPM 有一个名为 nodemailer-plugin-inline-base64 的包,它允许您将带有数据 uri 的图像发送到所有电子邮件提供商,如 gmail、outlook 等。

设置:

yarn add nodemailer nodemailer-plugin-inline-base64

试试看

var nodemailer = require('nodemailer');
var inlineBase64 = require('nodemailer-plugin-inline-base64');
transporter.use('compile', inlineBase64(cidPrefix: 'somePrefix_'));
transporter.sendMail(
    from: 'me@example.com',
    to: 'hello@mixmax.com',
    html: '&lt;img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlgAAAACCAYAAACE7KJkAAAAI0lEQVRYR+3DMQ0AAAgDsKlFzZxgEhOcbdIEAIBf7Y6qqn8P0MMQZPno7TMAAAAASUVORK5CYII=">'
);

祝你有美好的一天!

【讨论】:

以上是关于Gmail 阻止电子邮件模板中嵌入的小型嵌入式图像的主要内容,如果未能解决你的问题,请参考以下文章

使用 Gmail API 时,您能否以及如何在电子邮件中嵌入图像?

Python - 使用嵌入图像向 GMAIL 发送邮件

Gmail 中的 HTML 电子邮件 - 嵌入图像

将 Gmail 转换为 PDF:HTML 中的嵌入图像

电子邮件中的图像:链接还是嵌入?

发送嵌入图像的电子邮件 - 图像不可见