技术笔记:Indy的TIdSMTP改造,解决发送Html和主题截断问题

使用Indy来发邮件坑不少啊,只不过有比没有好吧,使用delphi6这种老工具没办法,只能使用了新一点的Indy版本9,公司限制。。。

1、邮件包含TIdText和TIdAttachment时会出现TIdText无法发送的问题

这个问题是因为Indy代码的bug导致的,也很奇怪这种Bug是因为没有经过测试呢?还是测试没有覆盖到?

问题出在SendBody方法上,这个在之前一篇中提到过《技术笔记:Indy控件发送邮件》

当时是解决“发送Html”的问题才使用到了TIdText这个组件,因为基类TIdMessageClient中的SendBody方法中如果存在TIdText和TIdAttachment时有一个Bug:

 if AMsg.MessageParts.TextPartCount > 1 then

必须>1这就有问题。因为只有一个TIdText所以这句话会导致无法发送body内容。所以解决方法是再添加一个相同的TIdText,之前测试还挺好的,但昨天发现反馈有人收到的邮件中有重复的body内容。也挺奇怪,我自己测试的时候没有呢?而且试了不好邮箱都正常的。。

解决办法比较简单,就是继承TIdSMTP,重写SendBody方法。把这一句改一下:

 if AMsg.MessageParts.TextPartCount >= 1 then

变成 >=吧,目前测试下来是正常的。至少在发邮件时不用再重复添加TIdText了。

2、邮件主题Subject超过一定的字符量就会出现截断

另外提求新需求要求主题增加一些内容,以便收件人可以一眼看出邮件是啥意思。挺简单的事情吧,结果发生了难过的事情。收到的邮件主题是截断的,而且后面的内容解析错误。心想这是个什么鬼。网上一找有同样的问题,原因也找到了:

【原因】Indy的IdMessage组件在生成待发送的邮件时,主题中有汉字时会按RFC2045~2047的base64编码规范对主题进行编码,base64要求编码后每行长度不能超过75(76)个字节;所以当主题过长时要分行。问题是IdMessage编码时,用了2对分行符<CR><LF><CR><LF>,而RFC规定<CR><LF><CR><LF>表示邮件中一节的结束,所以接收邮件的程序只会对第1行解码,其余的理解为邮件内容了。

可见Indy确实主要照顾了英文的使用,像中文这种复杂的点语言估计都没好好测试吧,另外以前只听说Indy问题多但一直没感觉到,现在接触多一些果然有所体会啊。当然高人也给出了解决方案,就是把这个<CR><LF><CR><LF>换成<CR><LF>这样就行了。

procedure TIdSmtpEx.SendHeader(AMsg: TIdMessage);
var
  LHeaders: TIdHeaderList;
begin
  LHeaders := AMsg.GenerateHeader;
  try
    //解决标题过长时导致的收件方解码错误问题
    LHeaders.Text := StringReplace(LHeaders.Text, #13#10#13#10, #13#10, [rfReplaceAll]);
    WriteStrings(LHeaders);
  finally
    FreeAndNil(LHeaders);
  end;
end;

#13#10就是回车和换行的意思,对应<CR><LF>

测试下来发现是正确的。

代码已经放到gitbub上:https://github.com/mini188/IndyMail

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

基于spring-boot的rest微服务框架

周末在家研究spring-boot,参考github上的一些开源项目,整了一个rest微服务框架,取之于民,用之于民,在github上开源了,地址如下:

1391
来自专栏源哥的专栏

在struts中使用国际化(i18n)

在struts中使用国际化(i18n)     i18n可以满足对系统的国际化,它的原理就是将页面上的所有标志都放到一个消息资源文件中,不同的语言要提供不同的消...

732
来自专栏【转载】DRF+Vue+Mysql_生鲜超市系统

八、商品详情页功能

(1)商品详情页只需要多继承一个类(mixins.RetrieveModelMixin)就可以了

1470
来自专栏超然的博客

web攻击

  最常见和基本的攻击WEB网站的方法。攻击者在网页上发布包含攻击性代码的数据。当浏览者看到此网页时,特定的脚本就会以浏览者用户的身份和权限来执行。通过XSS可...

1241
来自专栏Python攻城狮

Django教程(一)- Django视图与网址1.简介2.环境搭建3.安装pycharm4.Ubuntu下 正确安装VMware Tools5.Django主要模块6.Django基本命令7. Dj

Django 是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网站!

1462
来自专栏zhangdd.com

CentOS 7.0 systemctl使用说明

centos 7.0  引入了很多心得特性,感觉比较大的是sytemctl 命令的使用。

531
来自专栏苦逼的码农

Linux达人养成3--使用远程工具操作Linux

今天,我们讲讲用远程工具来管理我们的Linux,以及一些常用的网络命令。如果没还没学过基本的Linux命令以及网络配置,可以看我前两篇文章哦。

932
来自专栏菩提树下的杨过

silverlight: "[HtmlPage_NotEnabled] 调试资料字符串不可用"的解决

相信有不少人遇到过这个恶心的问题,xaml与cs编译正常,也能在浏览器里运行,但是就是无法在vs.net或blend里以【设计视图】方式打开,只能对着代码视图盲...

2017
来自专栏跟着阿笨一起玩NET

win7组件服务COM+应用程序编录错误解决办法

一般情况下,我们遇到过的COM+应用程序编录错误共有两个:(1)第一个是打开COM+应用程序时出现“编录错误,执行最后操作发生错误,错误代码8007042C-依...

2241
来自专栏地方网络工作室的专栏

Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(十)打包项目并发布到子目录

Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(十)打包项目并发布到子目录 前情回顾 通过上一章《Vue2+VueRou...

2368

扫码关注云+社区

领取腾讯云代金券