电子邮件模板图像显示在预览中,但不显示在 Gmail 中

email-templates Images are shown in preview but not in Gmail

我正在使用 email-template 包来发送样式化的电子邮件。在电子邮件预览中似乎一切正常(预览选项在包本身中给出。如果设置为真,它会在选项卡中呈现已发送的电子邮件预览)。但是当我在我的 gmail 帐户中收到电子邮件时,图片是不可见的。我可以看出设置/代码中的路径/图像存在,因为在预览中一切都放置得恰到好处。

    smtpTransport = nodemailer.createTransport(
      smtpTransport({
        host: 'smtp.gmail.com',
        port: 465,
        secure: true,
        jsonTransport: true,
        auth: {
          user: 'sender.example@gmail.com',
          pass: '123123',
        },
      })
    );
    
    smtpTransport.use('compile', base64ToS3());
    
    const templateWrapper = new Email({
      transport: smtpTransport,
      send: true,
      preview: true,
      views: {
        options: {
          extension: 'ejs',
        },
        root: path.join(__dirname, 'email/html/events'),
      },
      juice: true,
      juiceSettings: {
        tableElements: ['TABLE'],
      },
      juiceResources: {
        preserveImportant: true,
        webResources: {
          relativeTo: path.join(__dirname, 'email/assets'),
          images: true,
        },
      },
    });

这是我的 HTML 模板:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Efys - Welcome</title>
    <style>
      html {
        box-sizing: border-box;
      }
      *,
      *:before,
      *:after {
        box-sizing: border-box;
      }
      body {
        font-family: sans-serif;
        -webkit-font-smoothing: antialiased;
        font-size: 0.8rem;
        line-height: 1.4;
        margin: 0;
        padding: 0;
        -ms-text-size-adjust: 100%;
        -webkit-text-size-adjust: 100%;
      }
      .bg-brand-color-blue-dark {
        background-color: #033e75;
      }
      .bg-brand-color-gold-light {
        background-color: #f0ede6;
      }
      .bg-brand-color-gold-dark {
        background-color: #d0a345;
      }
      .bg-white {
        background-color: #ffffff;
      }

      .brand-color-gold-dark {
        color: #d0a345;
      }
      .brand-color-gold-light {
        color: #f0ede6;
      }
      .brand-color-blue-dark {
        color: #033e75;
      }
      .text-color-white {
        color: #ffffff;
      }
      .text-color-black {
        color: #000000;
      }

      .display-block {
        display: block;
      }
      .margin-top-0rem {
        margin-top: 0;
      }
      .margin-top-1rem {
        margin-top: 1rem;
      }
      .margin-top-2rem {
        margin-top: 2rem;
      }
      .margin-bottom-2rem {
        margin-bottom: 2rem;
      }
      .padding-full-1rem {
        padding: 1rem;
      }
      .padding-full-2rem {
        padding: 2rem;
      }
      .padding-top-2rem {
        padding-top: 2rem;
      }
      .padding-bottom-5rem {
        padding-top: 5rem;
      }

      .border-solid-black {
        border: 1px solid #000000;
      }
      .border-radius-half {
        border-radius: 0.5rem;
      }
      .border-radius-1rem {
        border-radius: 1rem;
      }
      .whitespace {
        white-space: normal;
      }
      .font-size-x1 {
        font-size: 1rem;
      }
      .font-size-x2 {
        font-size: 2rem;
      }

      a,
      a:visited {
        color: blue;
      }
      .text-decoration-none {
        text-decoration: none;
      }
      ol {
        padding-left: 15px;
      }
      p {
        margin-top: 1rem;
        margin-bottom: 0;
      }
      .strong {
        font-weight: bold;
      }
      h3 {
        margin-bottom: 0;
      }
      h3 + p {
        margin-top: 0;
      }
      .inline-icon {
        margin-right: 5px;
      }

      .flexbox {
        display: flex;
      }
      .flex-row {
        flex-direction: row;
      }
      .flex-nowrap {
        flex-wrap: nowrap;
      }
      .flexbox .cell {
        width: 50%;
      }
      .flexbox .cell:nth-child(2) {
        text-align: right;
      }

      .maximum-width {
        width: 100%;
        max-width: 36.25rem;
        margin: 0 auto;
      }
      .logo {
        width: 100%;
        max-width: 36.25rem;
        margin: 0 auto;
      }
      .logo img {
        border: 0 none;
        outline: 0 none;
        width: 100%;
        height: auto;
      }

      @media only screen and (max-width: 480px) {
        .footer > .flexbox .cell {
          width: 100%;
          text-align: center;
        }
        .footer > .flexbox .cell:nth-child(2) {
          text-align: center;
          margin-top: 1rem;
        }
        .footer > .flex-nowrap {
          flex-wrap: wrap;
        }
        .inner-cell.flexbox {
          display: block;
          max-width: 100%;
          margin: 0 auto;
        }
      }
    </style>
  </head>
  <body>
    <div
      class="wrapper display-block bg-brand-color-blue-dark padding-full-1rem"
    >
      <!-- logo -->
      <div class="logo display-block" style="margin: 0 auto;">
        <img
          class="display-block"
          src="efy-registration-header.jpg"
          alt="abc def"
          style="border-top-left-radius: 1rem; border-top-right-radius: 1rem;"
        />
      </div>

      <!-- content -->
      <div
        class="content display-block maximum-width bg-white text-color-black padding-full-2rem"
        style="border-bottom-left-radius: 1rem; border-bottom-right-radius: 1rem;"
      >
        <p class="strong">Dear <%= clientName %>,</p>

        <p>
          You have successfully registered for <%= efyTitle %> on <%= efyDay %> at <%= startTime %>
        </p>
        <p>Your Reference ID is: <%= referenceId %></p>
                <% if (displayAddress) { %>
            <p>Zoom link: <%= address %></p>
                <% } else { %>
            <p>
              Zoom link: You should receive an email update with the link to the
              live efy
            </p>
                <% } %>
        <h3>Zoom Instructions</h3>
        <p>To join a Zoom meeting on a computer or mobile device:</p>
        <ol>
          <li>
            Download the Zoom app from their Download Center
            <a href="https://zoom.us/download" target="_blank"
              >https://zoom.us/download</a
            >. Otherwise, you will be prompted to download and install Zoom when
            you click a join link.
          </li>
        </ol>
      </div>

      <!-- footer -->
      <div
        class="footer maximum-width text-color-white"
        style="margin: 1rem auto 5rem;"
      >
        <div
          class="flexbox flex-row flex-nowrap"
          style="justify-content: center; align-items: flex-end;"
        >
          <div class="cell">
            <div class="flexbox flex-row flex-nowrap inner-cell">
              <div class="col" style="margin-right: 0.5em;">
                <img
                  src="logo_icon.png"
                  alt="abc def"
                  width="50"
                  height="auto"
                />
              </div>
              <div class="col">
                Villa 1, Alwasl Rd. <br />
                Alsafa 2 <br />
                Dubai, United Arab Emirates
              </div>
            </div>

            <p>
              <span class="strong brand-color-gold-dark">T.</span>
              <a
                href="tel:+97143809298"
                class="text-decoration-none strong"
                style="color: #FFFFFF;"
                >+971 (0)4 380 9296</a
              >
            </p>
            <p class="margin-top-0rem">
              <span class="strong brand-color-gold-dark">E.</span>
              <a
                href="mailto:info@example.com"
                class="text-decoration-none strong"
                style="color: #FFFFFF;"
                >info@example.com</a
              >
            </p>
          </div>

          <div class="cell">
            <p>
              <span class="inline-icon"
                ><a href="#"
                  ><img
                    src="icon-facebook.png"
                    width="40"
                    height="auto"/></a
              ></span>
              <span class="inline-icon"
                ><a href="#"
                  ><img
                    src="icon-twitter.png"
                    width="40"
                    height="auto"/></a
              ></span>
              <span class="inline-icon"
                ><a href="#"
                  ><img
                    src="icon-instagram.png"
                    width="40"
                    height="auto"/></a
              ></span>
              <span class="inline-icon"
                ><a href="#"
                  ><img
                    src="icon-linkedin.png"
                    width="40"
                    height="auto"/></a
              ></span>
            </p>
            <p class="brand-color-gold-dark strong">@example.com</p>
            <p class="margin-top-0rem">
              <span class="strong brand-color-gold-dark">W.</span>
              <a
                href="//example.com"
                class="text-decoration-none strong"
                style="color: #FFFFFF;"
                >example.com</a
              >
            </p>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

当您加载 HTML 页面并使用如下图片时

<img
  src="icon-linkedin.png"
  width="40"
  height="auto"
/>

它实际上告诉浏览器,从加载 HTML 页面的同一目录加载图像。

问题来了。当您的电子邮件在 Gmail 中加载时,它也会告诉浏览器相同的信息,并且浏览器将无法找到该图像。

解法:

如果您是从后端发送的。然后上传任意publicurl中的图片。您可以在前端托管中上传图片并找到 link。然后直接使用link。您的图片需要 public 才能访问。

如果您没有任何其他选择或托管。在任何 public github/gitlab 存储库中上传图像并使用 link.

According to the docs for nodemailer-base64-to-s3,需要在base64ToS3方法中传入一些配置选项。它说 aws/params/Bucket 是必需的。

我相信以下内容应该会给您一个良好的开端:


smtpTransport.use('compile', base64ToS3({
    aws: {
        params: {
            Bucket: "bucket_name_here"
        }
    }
}));

另一个例子见https://github.com/forwardemail/nodemailer-base64-to-s3/blob/master/example.js