我正在开发一个需要每天发送电子邮件的java应用程序。我使用 Thymeleaf 从模板构建消息正文,将结果添加到 mime BodyPart,然后将该部分设置为消息的内容。目标是拥有一个目录,其中每个项目都是指向消息部分的链接。不幸的是,当我在 Gmail 中查看生成的电子邮件时,没有一个链接有效。
我输入了一些日志记录并验证了 html 是否正确生成。在目录中我有一些 html,例如:
<ul id="titles_6e8c478e-aabe-4789-ab22-8092e19c2dde" style="list-style: none; margin: 0 0 10px 0; padding-left: 15px; font-size: 13px;">
<li><a href="#message_2401_6e8c478e-aabe-4789-ab22-8092e19c2dde">A display test</a></li>
<li><a href="#message_2383_6e8c478e-aabe-4789-ab22-8092e19c2dde">Testing individual</a></li>
</ul>
根据消息中的一些 id 数据构建 href。页面下方的目标 html 如下所示:
<table class="message" width="100%" align="center" cellpadding="0" cellspacing="0" border="0" style="border-bottom: solid #ccc 1px;">
<tr>
<td style="font-size: 13px; color: #333333; padding-left: 15px; padding-bottom: 15px; padding-top: 15px;">
<a id="message_2401_6e8c478e-aabe-4789-ab22-8092e19c2dde"></a>
<span ><strong>A display test</strong></span><br/>
<p><a href="#pagetop">Top</a></p>
</td>
</tr>
</table>
<table class="message" width="100%" align="center" cellpadding="0" cellspacing="0" border="0" style="border-bottom: solid #ccc 1px;">
<tr>
<td style="font-size: 13px; color: #333333; padding-left: 15px; padding-bottom: 15px; padding-top: 15px;">
<a id="message_2383_6e8c478e-aabe-4789-ab22-8092e19c2dde"></a>
<span ><strong>Testing individual</strong></span><br/>
<p><a href="#pagetop">Top</a></p>
</td>
</tr>
</table>
到目前为止一切顺利。问题是,我的 html 在构建和发送消息期间的某个时刻被修改。当我检查收到的电子邮件的 html 时,我的 href 标签现在的格式如下:
<a href="#m_-2166845457075511738_message_2401_6e8c478e-aabe-4789-ab22-8092e19c2dde">A display test</a>
注意到添加的额外前缀了吗?就其本身而言,这不会成为问题,但是当我查看目标 html 时,它现在看起来像:
<a id="m_-2166845457075511738message_2401_6e8c478e-aabe-4789-ab22-8092e19c2dde"></a>
如果它们匹配,则额外的前缀并不重要,但是缺少下划线意味着所有这些链接现在都已损坏。
如果有帮助,我负责构建和发送电子邮件的代码如下所示:
public SimpleResponse sendEmail(List<String> toAddresses, String subject) throws IOException {
Properties prop = new Properties();
prop.put("mail.smtp.host", host);
prop.put("mail.smtp.port", port);
prop.put("mail.smtp.starttls.enable", "true");
prop.put("mail.smtp.auth", "false");
prop.put("mail.smtp.socketFactory.port", port);
prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
Session session = Session.getInstance(prop);
Message message = new MimeMessage(session);
Multipart multipart = new MimeMultipart();
try {
logger.info("Attempting to send email, " + subject + " to: " + recipients);
message.setFrom(new InternetAddress("[email protected]"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));
message.setSubject(subject);
//generate the html content of the email from a thymeleaf template
String digestHtml = generateDailyDigestFromTemplate(learnerEmail, subscribedMessages);
//this line outputs the html and everything looks as expected
System.out.println(digestHtml);
BodyPart dailyDigestBody = new MimeBodyPart();
dailyDigestBody.setContent(digestHtml, "text/html");
multipart.addBodyPart(bodyPart);
message.setContent(multipart);
Transport.send(message);
} catch (MessagingException e) {
logger.error("Failed to send email", e);
return new SimpleResponse("sendEmail: " + subject, false,
"Failed to sent email to: " + toAddresses + " with error: " + e.getMessage());
}
logger.info("Successfully sent email, " + subject + " to: " + recipients);
return new SimpleResponse("sendEmail: " + subject, true, "Successfully sent email to: " + toAddresses);
}
此时我有点卡住了。知道是什么原因造成的吗?我该怎么做才能修复它?
更新:我已经设法缩小问题的原因,但我仍然不确定如何解决它。问题出在 Gmail 客户端上。如果我单击“更多”菜单并选择“显示原始内容”,则 html 看起来非常好。只有当我在客户端中检查它时,才会添加额外的文本。
您所面临的电子邮件链接具有额外前缀的问题与 Gmail 在呈现电子邮件时修改电子邮件的 HTML 内容的方式有关。
要解决此问题并确保您的链接正常工作,您可以考虑以下选项:
使用绝对 URL: 您可以使用绝对 URL,而不是使用相对锚链接(例如 href="#message_2401_6e8c478e-aabe-4789-ab22-8092e19c2dde")。这些是完整的 URL,其中包含电子邮件中目标的完整地址。 Gmail 不太可能修改绝对网址。例如:
<a href="https://www.yourwebsite.com#message_2401_6e8c478e-aabe-4789-ab22-8092e19c2dde">A display test</a>
最小化 JavaScript 和事件属性
避免在电子邮件中使用基于 JavaScript 的操作,因为这可能会触发 Gmail 进行额外的修改。同样,尽量减少 onclick 等事件属性的使用,这在电子邮件客户端中可能会出现问题。
如果它解决了您的问题,请将其标记为答案。谢谢你。