iT邦幫忙

0

PHP在POSTFIX送出的html格式信在Outlook中成為文字格式的問題

大家好,我使用Ubuntu 8.04 server架站,加上Postfix server來讓網站有回覆的功能。但使用PHP的mail函數發出的信件,在Outlook收到信時,都只能呈現文字格式,所有的html原始碼都被一字不漏的呈現出來。
但使用sendmail的時候不會有這樣的情形,(只是使用sendmail的時候,PHP執行Mail函數時,會停頓很久才送出…)
請問我該朝哪個方向去查原因?

試試用 outlook (express) 送出 html 格式信件,
到該 postfix 看看,是不是也是同樣的狀況?
如果是的話,才可能是 postfix 的問題,
如果不是的話,就是得看看您的 PHP 碼,
有沒有畫出 Attachement字樣、Base64 或 QP 編碼出來?
如果是我
我會在Outlook那台電腦裝WireShark

同樣內容的信
先用Sendmail寄一次
再用Postfix寄一次
然後比對兩份內容有何不同

2 個回答

18
bizpro
iT邦大師 1 級 ‧ 2009-06-09 09:38:55
最佳解答

沒有看到您的程式碼, 請參考:
http://tw.php.net/manual/en/function.mail.php
基本上應該是
// To send HTML mail, the Content-type header must be set
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

看更多先前的回應...收起先前的回應...
dasu88 iT邦研究生 5 級 ‧ 2009-06-09 09:43:08 檢舉

謝謝你的回應,我PHP程式碼是正確的,我甚至把manual裡的範例整個貼來測試,也是一樣的結果。
用sendmail來跑,就會正常,所以我想問題出在postfix這個環節。

fillano iT邦超人 1 級 ‧ 2009-06-09 11:00:04 檢舉

用PHP_EOL來分行看看,請看一下manual的註解。

dasu88 iT邦研究生 5 級 ‧ 2009-06-09 13:02:03 檢舉

加上PHP_EOL也相同。

fillano iT邦超人 1 級 ‧ 2009-06-09 14:24:26 檢舉

用thunderbird收信呢?

dasu88 iT邦研究生 5 級 ‧ 2009-06-09 14:54:42 檢舉

信件傳送到gmail看也一樣,所以目前只能猜測問題出在postfix這邊。因為改為sendmail就正常。(但執行傳送mail的php很緩慢)

dasu88 iT邦研究生 5 級 ‧ 2009-06-09 14:57:48 檢舉

回應bizpro:
我先移除sendmail
指令:sudo apt-get remove sendmail
再裝上postfix
指令:sudo apt-get -y install postfix
php.ini中開啟下列這行(原本註解拿掉…)
sendmail_path = /usr/sbin/postfix -t -i

以上,做完後,重啟服務跟重新啟動server都試過了…

fillano iT邦超人 1 級 ‧ 2009-06-09 15:58:31 檢舉

直接在console用postfix送html格式的郵件來測試看看,是不是也有問題。

ricky0512 iT邦新手 5 級 ‧ 2009-06-09 18:03:07 檢舉

把 html 的部份用附件的方式送出也是一樣的結果嗎?

dasu88 iT邦研究生 5 級 ‧ 2009-06-09 21:40:51 檢舉

我的需求比較單純,只是需要php下的smtp功能,也沒有拿它當mail server的考量。兩位提的測試方式,我不知該如何進行,因為我沒在console直接收發信件過,對這部份不知如何下手測試。請問有參考資料嗎?

bizpro iT邦大師 1 級 ‧ 2009-06-09 21:42:56 檢舉

php的mail()是綁Sendmail的sendmail. 而當您安裝好postfix後, postfix 產生了一個替代Sendmail的sendmail 如/usr/sbin/sendmail, 因此應該用/usr/sbin/sendmail
sendmail_path = /usr/sbin/sendmail -t -i
試試看囉

dasu88 iT邦研究生 5 級 ‧ 2009-06-09 21:51:29 檢舉

謝謝bizpro,在上面的回覆時,我就發現我有一篇回覆有誤了。
我的php.ini裡設定確實是如下:
sendmail_path = /usr/sbin/sendmail -t -i
而不是
sendmail_path = /usr/sbin/postfix -t -i
所以這部份,也不是問題的成因。

bizpro iT邦大師 1 級 ‧ 2009-06-09 23:05:15 檢舉

您的Postfix是在php之後裝的嗎?

dasu88 iT邦研究生 5 級 ‧ 2009-06-09 23:09:35 檢舉

是的,postfix是在php之後安裝的。
另、剛測出了一個方向,發現信件如果直接發往gmail,則是正常的(只是會被視為垃圾信)
因先前我是發往公司的exchange server,再轉寄一份到gmail,如此只會看到純文字格式。
這是否代表問題出在exchange這端?
但我不明白,為何sendmail可以正常的傳送?

Gmail 絕對不能視為常例!因為他們實在是太厲害了,就算你Mail沒有定義好是什麼字碼什麼的,就自動可辨識出來。
而且,有關Gmail的測試,只能說是 Gmail 的 Client 辨識能力很強,比較不是 Mail Server 的議題。
至於利用 Gmail 的 POP3 功能來收信,是否 Gmail 的 Mail Server 會不會對信件像 Gmail 的 Client 來做些處理再給您的 POP3 Client 來收?我沒試過及觀察過,但推測應不會做此處理。所以您用 POP3 收 Gmail 的測試信,看是不是還是正常?

幾個問題的檢查:
1.

發往公司的exchange server,再轉寄一份到gmail
是在 exchang server 上的帳號設成 像 sendmail 上的 forward 或 aliases 的自動轉寄方式來轉寄嗎?
2.CharSet 是設什麼?
3.信件內容的 Encoding 是什麼? QP?Base64?
4.通常要寄 HTML 信件的程式,應要有定義 該型式為 multipart/related,
並以 attachment 的方式包起來,再定義宣告上述的 2. 3. 是什麼,然後再以 3. 編碼方式 才畫出信件才送出。
php 的程式要確認有以上的動作,才再討論是不是 Mail Server 的問題。

fillano iT邦超人 1 級 ‧ 2009-06-10 09:19:27 檢舉

我不是用Ubuntu(我用Centos),所以做法可能不一樣,但是可以參考。
Centos 的sendmail是一個link,透過一個mta這個link到/usr/sbin/sendmail.sendmail或是/usr/sbin/sendmail.postfix(大小寫可能要改一下)

所以你要測試的話,可以透過sendmail.postfix -t來測試。只要輸入完整的信件包含header跟body就可以。也可以用標準輸入重導到檔案。

例如下面是一個測試的例子:

To: fillano@example.com
Subject: test for mail
MIME-Version: 1.0
Content-type: text/html; charset=iso-8859-1

<p><b>test mail</b></p>
<table border="1" cellpadding="0" cellspacing="0">
<tr><td>row1-1</td><td>row1-2</td></tr>
<tr><td>row2-1</td><td>row2-2</td></tr>
</table>

.

單一個句點就會結束輸入,這樣重複測試就很方便。例如檔名叫做testmail的話,那只要在console使用:
sendmail.postfix -t < testmail

就可以。如果不想用.作為結束,那可以加上-i選項。(php的mail函數只是這樣呼叫它而已)

另外,送信的環節很多,建議你可以自己多用幾種方案測試一下,例如不同的pop3/imap還有mua等等。

請參閱 http://code.web-max.ca/misc\_htmlemail.php
在您的php程式多一些的 header 設定:
$boundary = uniqid("HTMLEMAIL");
$headers .= "Content-Type: multipart/alternative;".
"boundary = $boundary\r\n\r\n";
$headers .= "This is a MIME encoded message.\r\n\r\n";
$headers .= "--$boundary\r\n".
"Content-Type: text/plain; charset=ISO-8859-1\r\n".
"Content-Transfer-Encoding: base64\r\n\r\n";
$headers .= chunk_split(base64_encode(strip_tags($HTML)));
$headers .= "--$boundary\r\n".
"Content-Type: text/html; charset=ISO-8859-1\r\n".
"Content-Transfer-Encoding: base64\r\n\r\n";
$headers .= chunk_split(base64_encode($HTML));
並把送出的動作改為:
mail($to,$subject,"",$headers);
看會不會是老問題?

bizpro iT邦大師 1 級 ‧ 2009-06-12 15:02:40 檢舉

您有檢視過Postfix到Exchange, Postfix到Gmail的Email, 和Sendmail到Exchange的原始檔的內容差異嗎? 可以樣張分寄後檢視差異,提供參考?

12
灌籃高手
iT邦高手 1 級 ‧ 2009-06-09 11:42:07

改用phpmailer試試看!

dasu88 iT邦研究生 5 級 ‧ 2009-06-09 13:02:41 檢舉

謝謝你,但我希望維持在現有的mail函數使用架構下,解決這個問題。

我要發表回答

立即登入回答