设为首页 加入收藏

TOP

技术笔记:Indy控件发送邮件(二)
2017-10-10 12:07:21 】 浏览:8316
Tags:技术 笔记 Indy 控件 发送 邮件
容易做样式,不太好看。所以就要支持Html格式。看了看网上的资料,就是使用另一个Indy类可以实现TIdText。

    with TIdText.Create(IdMessage1.MessageParts, objMailBody) do
    begin
      ContentType:='text/html;charset=utf-8';
      ContentTransfer := 'quoted-printable'; //不能用base64,indy控件没实现
    end;

和附件的使用方法类似,只是要设定一下格式。只不过让人失望了,发过去没有效果啊。。没有效果啊。。接收到的邮件正文是空白的,查看原文:

--=_NextPart_2rfkindysadvnqw3nerasdf
Content-Type: text/plain
Content-Transfer-Encoding: 7bit


--=_NextPart_2rfkindysadvnqw3nerasdf
Content-Type: application/octet-stream; name="Logs_2016-01-10[60001].7z"

 

这是QQ邮箱中收到的正文,发现在附件与正文之间的内容是空白,没有收到啊。再看看Foxmail(微软exchage)

------=_002_NextPart335103774317_=----
Content-Type: text/html;
charset="GB2312"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; charset=3Dgb2312">
<META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version 14.01.0421.=
002">
<TITLE>=C8=D5=D6=BE=A3=BA2016-01-10[60001]</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

</BODY>
</HTML>
------=_002_NextPart335103774317_=------

------=_001_NextPart645231448141_=----
Content-Type: application/octet-stream;
name="Logs_2016-01-10[60001].7z"

这倒是有一段html内容,只是body部分显示的是空白。。后来在网上看到一篇文章才发现是indy的一个bug。链接

TIdSMTP是最终发送邮件的类,发送的代码主要是在它父类TIdMessageClient中实现。SendBody方法,看看代码片段:

      if AMsg.MessageParts.TextPartCount > 1 then
      begin
        WriteLn('Content-Type: multipart/alternative; '); {do not localize}
        WriteLn('        boundary="' + IndyMultiPartAlternativeBoundary + '"'); {do not localize}
        WriteLn('');
        for i := 0 to AMsg.MessageParts.Count - 1 do
        begin
          if AMsg.MessageParts.Items[i] is TIdText then
          begin
            WriteLn('--' + IndyMultiPartAlternativeBoundary);
            DoStatus(hsStatusText,  [RSMsgClientEncodingText]);
            WriteTextPart(AMsg.MessageParts.Items[i] as TIdText);
            WriteLn('');
          end;
        end;
        WriteLn('--' + IndyMultiPartAlternativeBoundary + '--');
      end
      else begin

TextPartCount > 1才会去写入TIdText的内容,我的天,这玩意有点坑人啊。。于是我也学着别人的方法再添加一次,本文最初那段代码已经知道用法了:

    //可能是Indy的bug,需要创建两次TIdText才能成功发送内容
    with TIdText.Create(IdMessage1.MessageParts, objMailBody) do
    begin
      ContentType:='text/html;charset=utf-8';
      ContentTransfer := 'quoted-printable'; //不能用base64,indy控件没实现
    end;
    with TIdText.Create(IdMessage1.MessageParts, objMailBody) do
    begin
      ContentType := 'text/html;charset=utf-8';
      ContentTransfer := 'quoted-printable'; //不能用base64,indy控件没实现
    end;

 

再说乱码问题

前面在解决乱码问题时提到了Content-Transfer-Encoding,看别家邮件发送的内容可以是Base64,那么我想这应该是比较好的一种方法,于是就设置了一下,呵呵哒。跪了。然后只能继续查看组件的源代码,还是TIdMessageClient的SendBody方法,其中有个子函数:WriteTextPart。

  procedure WriteTextPart(ATextPart: TIdText);
  var
    Data: string;
    i: Integer;
  begin
    if Length(ATextPart.ContentType) = 0 then
      ATextPart.ContentType := 'text/plain'; {do not localize}
    if Length(ATextPart.ContentTransfer) = 0 then
      ATextPart.ContentTransfer := 'quoted-printable'; {do not localize}
    WriteLn('Content-Type: ' + ATextPart.ContentType); {do not localize}
    WriteLn('Content-T
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Firemonkey TComboBox 下拉菜单字.. 下一篇Firemonkey 在 iOS 平台能显示更..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目