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

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

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

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

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

 if AMsg.MessageParts.TextPartCount >  then

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

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

 if AMsg.MessageParts.TextPartCount >=  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, ####, ##, [rfReplaceAll]);
WriteStrings(LHeaders);
finally
FreeAndNil(LHeaders);
end;
end;

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

测试下来发现是正确的。

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

技术笔记:Indy的TIdSMTP改造,解决发送Html和主题截断问题的更多相关文章

  1. 解决一个 MySQL 服务器进程 CPU 占用 100%解决一个 MySQL 服务器进程 CPU 占用 100%的技术笔记》[转]

    转载地址:http://bbs.chinaunix.net/archiver/tid-1823500.html 解决一个 MySQL 服务器进程 CPU 占用 100%解决一个 MySQL 服务器进程 ...

  2. IPV6技术笔记(剖析IPv4toIPv6)

    IPV6技术笔记 IPv6地址入门概念 什么是IPv6? IPv6,全称Internet Protocol version 6,即网际协议版本6,也叫互联网通信协议第六版.是互联网工程任务组(IETF ...

  3. PHP实现日志处理类库 - 【微信开发之微电商网站】技术笔记之二

    继上篇文章[微信开发之微电商网站]技术笔记之一,昨日做了日志处理的功能. 对于现在的应用程序来说,日志的重要性是不言而喻的.很难想象没有任何日志记录功能的应用程序运行在生产环境中.日志所能提供的功能是 ...

  4. RocketMQ 源码学习笔记————Producer 是怎么将消息发送至 Broker 的?

    目录 RocketMQ 源码学习笔记----Producer 是怎么将消息发送至 Broker 的? 前言 项目结构 rocketmq-client 模块 DefaultMQProducerTest ...

  5. RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的?

    目录 RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的? 前言 项目结构 rocketmq-client 模块 DefaultMQProducerTest Roc ...

  6. 🏆【Alibaba中间件技术系列】「RocketMQ技术专题」Broker配置介绍及发送流程、异常(XX Busy)问题分析

    参考资料 Rocketmq官网:http://rocketmq.apache.org/ Rocketmq的其它项目:https://github.com/apache/rocketmq-externa ...

  7. RabbitMQ 入门系列:3、基础编码:官方SDK的引用、链接创建、单例改造、发送消息、接收消息。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  8. extjs folder is lost解决方法 和 FineUI主题切换时 iframe内的内容主题不变的解决方法

    错误原因:extjs包和FineUI版本不一致 或者是 webconfig配置中 没有设置为任何人可访问  解放方法下载和FineUI版本相同的extjs包就ok了 解决方法:FineUI主题切换时 ...

  9. Android菜鸟的成长笔记(6)——剖析源码学自定义主题Theme

    原文:Android菜鸟的成长笔记(6)--剖析源码学自定义主题Theme 还记得在Android菜鸟的成长笔记(3)中我们曾经遇到了一个问题吗?"这个界面和真真的QQ界面还有点不同的就是上 ...

随机推荐

  1. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  2. 【翻译】MongoDB指南/CRUD操作(四)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(四) 1 查询方案(Query Plans) MongoDB 查询优化程序处理查询并且针对给定可利用的索引选 ...

  3. 安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路

    针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest ...

  4. [C#] 简单的 Helper 封装 -- RegularExpressionHelper

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. 玩转spring boot——结合jQuery和AngularJs

    在上篇的基础上 准备工作: 修改pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  6. 【知识必备】RxJava+Retrofit二次封装最佳结合体验,打造懒人封装框架~

    一.写在前面 相信各位看官对retrofit和rxjava已经耳熟能详了,最近一直在学习retrofit+rxjava的各种封装姿势,也结合自己的理解,一步一步的做起来. 骚年,如果你还没有掌握ret ...

  7. XAMARIN.ANDROID SIGNALR 实时消息接收发送示例

    SignalR 是一个开发实时 Web 应用的 .NET 类库,使用 SignalR 可以很容易的构建基于 ASP.NET 的实时 Web 应用.SignalR 支持多种服务器和客户端,可以 Host ...

  8. Android中AlarmManager使用示例(持续更新,已经更改)

    现在普遍的手机都会有一个闹钟的功能,如果使用Android来实现一个闹钟可以使用AtarmManager来实现.AtarmManager提供了一种系统级的提示服务,允许你安排在将来的某个时间执行一个服 ...

  9. maven的pom.xml关系依赖书写顺序

    今天遇到了一个情况,以前代码编译没有问题,升级了hbase客户端phoenix驱动,又调整了thrift的关系依赖的位置,放到了这个驱动后面. 如下: 导致了一个thrift接口类编译报错: 检查这个 ...

  10. mac好用的markdown编辑器

    在刚开始接触markdown的时候,就被吸引了.此后一直在找贴心的好用的markdown编辑器.印象笔记和马克飞象配合着用也是挺好的,唯一的缺点就是比较封闭,发个笔记的链接给同学,还得注册才能看,导致 ...