筆記遇到一個問題:Claws Mail不識別PHPMailer發送的附件,經過烽數次在網上找資料,終于找到原因并解決,現在把原因及解決辦法整理如下.
環境:Claws Mail 3.9.1, PHP 5.4.16,PHPMailer 5.2.6 c5e9f7873f
現象:PHPMailer 發送帶附件的郵件,直接使用 AddAttachment() 方法
$mailer->AddAttachment($attach_file);
沒有其他設置,Claws Mail 收到信以后,查看郵件內容為空白, 附件欄顯示:
message/rfc822
multipart/mixed
以下就是空白了, 而能夠正常識別附件的郵件,附件欄內容一般為:
- message/rfc822
- multipart/mixed
- text/plain
- text/html (這個是附件的 mime 類型)
gmail 和 mutt 中識別這樣的郵件是正常的.
分析:通過對比正常和不正常的郵件原始碼,發現不正常郵件在聲明內容是分節之后,多了一句傳輸編碼聲明,比如:
- Content-Type: multipart/mixed;
- boundary="b1_95a848b14cb4385965320b915d5829dd"
- Content-Transfer-Encoding: base64 //開源軟件:Vevb.com
最后的 Content-Transfer-Encoding 就是比正常郵件多的一行,由于郵件原始碼的這個部分,只是用來聲明后續郵件是多個部分組成,并定義了每個部分的辨識邊界 boundary,并沒有實際的內容,所以應當是不需要聲明編碼類型的,在 PHPMailer 中相關代碼為:
- public function GetMailMIME() {
- $result = '';
- switch($this->message_type) {
- case 'inline':
- $result .= $this->HeaderLine('Content-Type', 'multipart/related;');
- $result .= $this->TextLine("tboundary="" . $this->boundary[1].'"');
- break;
- case 'attach':
- case 'inline_attach':
- case 'alt_attach':
- case 'alt_inline_attach':
- $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
- $result .= $this->TextLine("tboundary="" . $this->boundary[1].'"');
- break;
- case 'alt':
- case 'alt_inline':
- $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
- $result .= $this->TextLine("tboundary="" . $this->boundary[1].'"');
- break;
- default:
- // Catches case 'plain': and case '':
- $result .= $this->TextLine('Content-Type: '.$this->ContentType.'; charset='.$this->CharSet);
- break;
- }
- //RFC1341 part 5 says 7bit is assumed if not specified
- if ($this->Encoding != '7bit') {
- $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
- }
特意加上了這個申明,因為按照 RFC1341,7bit 編碼類型是默認的.
解決:或許問題是出在 Claws Mail 上,但我暫時只能修改 PHPMailer 來適應這個問題了,上面的問題弄清楚之后,在 multipart 后面不添加傳輸編碼聲明即可:
- //RFC1341 part 5 says 7bit is assumed if not specified
- // Not after multipart/mixed, claws-mail will not recoginize attachment
- if (($this->Encoding != '7bit') && (!in_array($this->message_type, array(
- 'attach',
- 'inline_attach',
- 'alt_attach',
- 'alt_inline_attach',
- )))) {
- $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
- }
終于解決了這個問題,現在我們可以放心的用PHPMailer發送附件了.
新聞熱點
疑難解答