程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 技術筆記:Indy的TIdSMTP改造,解決發送Html和主題截斷問題,indytidsmtp

技術筆記:Indy的TIdSMTP改造,解決發送Html和主題截斷問題,indytidsmtp

編輯:Delphi

技術筆記:Indy的TIdSMTP改造,解決發送Html和主題截斷問題,indytidsmtp


使用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

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved