zoukankan      html  css  js  c++  java
  • 技术笔记: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

  • 相关阅读:
    模板
    2019牛客暑期多校训练营(第五场)
    Codeforces
    Codeforces
    SCUT
    模板
    Codeforces
    2019 Multi-University Training Contest 4
    Codeforces
    Codeforces
  • 原文地址:https://www.cnblogs.com/5207/p/5177020.html
Copyright © 2011-2022 走看看