JavaScript列印頁面及mailto寄信亂碼

接續前兩篇文章,從FancyBox到達申請表頁面後,對方要求可以透過(1)印表機列印申請表,(2)透過email寄送申請表。這篇文章小蛙要來說明怎麼透過JavaScript列印頁面以及用email寄送申請表,小蛙在處理mailto的時候遇到亂碼問題卡了一天,也會在這篇文章中說明。

  • JavaScript列印頁面

JavaScript列印頁面非常簡單,只需要一行就可以達成,更多詳細資料可以參考Javascript呼叫IE列印以及預覽列印的方法@小峰峰的筆記本

&lt;input type="button" onclick="<span style="color: #ff0000;"><strong>print()</strong></span>" value="列印申請表"&gt;
  • JavaScript寄送電子郵件

JavaScript寄送電子郵件指令也非常簡單,但是隱藏的問題其實還蠻多的,小蛙先介紹寄送電子郵件的指令。

<input type="button" onclick="sendMail(true);" value="使用Big5寄送(Outlook)">
<input type="button" onclick="sendMail(false);" value="使用UTF-8寄送">

小蛙用了sendMail()來讓使用者自行選擇要用哪種方式寄送等等再說明原因。JavaScript程式碼寄信程式碼如下,因為小蛙只用到簡單的寄件人、主旨及內容,更多詳細設定請參閱用mailto寄信 @ 螞蟻的HTML

<script type="text/javascript">
  // 基本寄信,沒有判斷編碼
  function sendMail(){
    var text_title = "這是一封透過JavsScript寄送的郵件主旨";
    var text_body  = "這是內文的部分。";
    sendmail = "mailto:[email protected]?subject=" + text_title;
    sendmail += "&body=" + text_body;
    location.href = sendmail;
  }
</script>

如果要用到換行的話,必須使用%0A。這個範例可能有些人跑起來是OK的,有些人卻得到亂碼,接下來小蛙要記錄一下自己的做法,也許有更好的做法,但時間緊迫只好先用這種特殊方式來解決。

  • JavaScript mailto 亂碼解決

目前小蛙找不到可以自動判斷要用什麼編碼的方法,也就是像上面的兩個按鈕,透過Big5寄送,或是透過UTF-8寄送,當小蛙以為就只有那麼簡單的時候又發現還要多一個條件判斷IE。Microsoft Outlook或Outlook Express會亂碼的原因是Outlook只能接受BIG5的編碼,但透過頁面location.href引導過去的參數會變成UTF-8,所以不管怎麼試只要編碼不是BIG5在Outlook就一定會出現亂碼,但又找不到方法可以判斷客戶端在點了按鈕之後所呼叫的是Outlook還是透過Webmail寄送,像小蛙的電腦點了之後會跳出瀏覽器,透過gmail送出郵件,而不是使用Outlook。

要確保送出的資料一定是用BIG5來編碼,在Java可以透過以下方式編碼。

java.net.URLEncoder.encode("一定要轉成BIG5編碼", "BIG5");

小蛙直接以自己的例子來說明,所有的頁面都是透過UTF-8編碼,包括使用者輸入的表單也是,這邊卡了一個問題是java.net.URLEncoder.encode()這個是Java的function,所以必須要在Server端才可以使用,也就是說使用者輸入完的資料沒有辦法直接透過java.net.URLEncoder.encode()來處理,這邊小蛙只好把所有的參數POST到另一頁sendMail.jsp專門處理亂碼及送出,以下是sendMail.jsp中Java編碼的部分。

String applyName = request.getParameter("applyName") == null ? "" : new String(request.getParameter("applyName").getBytes("ISO-8859-1"), "UTF-8");
String applyNameB = java.net.URLEncoder.encode("名稱:"   + applyName).replaceAll("[+]", " ");

編碼邏輯部分如下(以下是小蛙的dirty code,JavaScript跟Java夾雜,硬要分還是可以分的開,要怎麼處理就看自己的規畫囉!):

&lt;script type="text/javascript"&gt;
  var text_title = "&lt;%=title%&gt;";
&lt;%
  //也就是按下上面的「使用Big5寄送(Outlook)」
  if("true".equals(big5)){
%&gt;
      // 這邊無論是哪個瀏覽器都務必要使用 <span style="color: #ff0000;"><strong>big5</strong></span> 送出
      text_title = "&lt;%=title<span style="color: #ff0000;"><strong>B</strong></span>%&gt;";
      text_body  = "%0A" + ("&lt;%=applyName<span style="color: #ff0000;"><strong>B</strong></span>%&gt;");
      ....
&lt;%
  }else{
      if("IE".equals(browser)){
%&gt;
          // 如果瀏覽器是IE,還要額外做encodeURI處理
          text_title = <strong><span style="color: #ff0000;">encodeURI</span></strong>(text_title);
          text_body  = "<span style="color: #ff0000;"><strong>%0A</strong></span>" + <strong><span style="color: #ff0000;">encodeURI</span></strong>("名稱:&lt;%=applyName%&gt;");
          ....
&lt;%
      }else{
%&gt;
          // Firefox, Chrome直接傳送即可
          text_title = (text_title);
          text_body  = "<span style="color: #ff0000;"><strong>%0A</strong></span>" + ("物件名稱:&lt;%=applyName%&gt;");
&lt;%
      }
  }
%&gt;
  mail_str = "mailto:[email protected]?subject=" + text_title;
  mail_str += "&amp;body=" + text_body;
  location.href = mail_str;
&lt;/script&gt;

好吧!還有時間的話再來看看要不要把這些Code清乾淨一些…天啊!Web工程師最怕看到的應該就是亂碼,每次一遇到亂碼問題就會卡一段時間 … 還是希望瀏覽器的行為模式可以統一呀!上面的方法可以「手動」解決亂碼問題,讓使用者自己點選是否透過Outlook或是透過Webmail傳送,而在瀏覽器的特殊行為上小蛙也做了判斷,最有問題的IE特別隔離出來,希望之後能看到更好的做法><。
這方法有一些不足的地方
(1)程式碼太醜,Java跟JavaScript全都混在一起(剛上面提到可以拆的開!!!)
(2)沒辦法做到完全自動判斷,還要讓使用者點選
(3)小蛙只測試了IE8, FF7.0.1, Chrome 16.0.912.63
(4)如果使用者預設瀏覽器是IE,而透過非IE瀏覽器去點選寄送mail,有些情況可以,有些情況不行,這個部份處理起來真的沒完沒了,真正遇到再說了 = =
打完收工,繼續處理其他工作,希望可以不要抱著工作跨年。

    1 個回應

    1. richstill表示:

      可以参考一下
      http://axzjhy.blog.163.com/blog/#m=0

    發佈留言

    發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

    這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料