大家好,我使用Ubuntu 8.04 server架站,加上Postfix server來讓網站有回覆的功能。但使用PHP的mail函數發出的信件,在Outlook收到信時,都只能呈現文字格式,所有的html原始碼都被一字不漏的呈現出來。
但使用sendmail的時候不會有這樣的情形,(只是使用sendmail的時候,PHP執行Mail函數時,會停頓很久才送出…)
請問我該朝哪個方向去查原因?
沒有看到您的程式碼, 請參考:
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";
謝謝你的回應,我PHP程式碼是正確的,我甚至把manual裡的範例整個貼來測試,也是一樣的結果。
用sendmail來跑,就會正常,所以我想問題出在postfix這個環節。
用PHP_EOL來分行看看,請看一下manual的註解。
加上PHP_EOL也相同。
用thunderbird收信呢?
信件傳送到gmail看也一樣,所以目前只能猜測問題出在postfix這邊。因為改為sendmail就正常。(但執行傳送mail的php很緩慢)
以上,做完後,重啟服務跟重新啟動server都試過了…
直接在console用postfix送html格式的郵件來測試看看,是不是也有問題。
把 html 的部份用附件的方式送出也是一樣的結果嗎?
我的需求比較單純,只是需要php下的smtp功能,也沒有拿它當mail server的考量。兩位提的測試方式,我不知該如何進行,因為我沒在console直接收發信件過,對這部份不知如何下手測試。請問有參考資料嗎?
php的mail()是綁Sendmail的sendmail. 而當您安裝好postfix後, postfix 產生了一個替代Sendmail的sendmail 如/usr/sbin/sendmail, 因此應該用/usr/sbin/sendmail
sendmail_path = /usr/sbin/sendmail -t -i
試試看囉
謝謝bizpro,在上面的回覆時,我就發現我有一篇回覆有誤了。
我的php.ini裡設定確實是如下:
sendmail_path = /usr/sbin/sendmail -t -i
而不是
sendmail_path = /usr/sbin/postfix -t -i
所以這部份,也不是問題的成因。
您的Postfix是在php之後裝的嗎?
是的,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 的問題。
我不是用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);
看會不會是老問題?
您有檢視過Postfix到Exchange, Postfix到Gmail的Email, 和Sendmail到Exchange的原始檔的內容差異嗎? 可以樣張分寄後檢視差異,提供參考?