mailto: で始まるリンクをクリックすると、利用者のメールソフトが開き、宛先の入った新しいメールが作られます。宛先だけでなく、件名 (subject) や本文 (body) もあらかじめ入れておけます。ただし、日本語をそのまま書くと、メールソフトによっては件名が文字化けすることがあります。ここでは、文字化けさせないための符号化の方法と、あわせて考えたい使い分けを説明します。

mailto: の基本の書き方

宛先のあとに ? を付け、名前=値 の組を & でつなぎます。

<a href="mailto:info@example.com?subject=Hello&body=Thank%20you">メールを送る</a>

使える名前には、subject (件名)、body (本文)、cc、bcc などがあります。宛先を複数にするときは、アドレスを , で区切ります。

値の中に、&、=、?、#、%、空白などの記号があると、区切りの記号と見分けがつかなくなります。そのため、値は必ず URL の形に符号化 (エンコード) して書きます。

日本語は UTF-8 でパーセント符号化する

今の mailto: の仕様 (RFC 6068) では、値の文字を UTF-8 のバイト列にし、1 バイトずつ % と 16 進数の 2 けたで表すことになっています。これをパーセント符号化と呼びます。JavaScript では encodeURIComponent() がちょうどこの処理をします。

encodeURIComponent("お問い合わせ");
// → "%E3%81%8A%E5%95%8F%E3%81%84%E5%90%88%E3%82%8F%E3%81%9B"

HTML に直接書くなら、符号化した結果を href に入れます。手で符号化すると間違えやすいので、JavaScript で組み立てるのが確実です。次の例では、HTML に宛先だけの mailto: のリンクを書いておき、件名と本文を JavaScript で付け足します (組み立てた結果をコンソールで確かめて、HTML に貼り付けてもかまいません)。

// 件名と本文から mailto: の URL を組み立てる
function buildMailto(address, subject, body) {
  const params = [
    "subject=" + encodeURIComponent(subject),
    // 改行は CRLF (%0D%0A) にそろえてから符号化する
    "body=" + encodeURIComponent(body.replace(/\r?\n/g, "\r\n")),
  ];
  return "mailto:" + address + "?" + params.join("&");
}

const link = document.querySelector("a.js-mail");
link.href = buildMailto(
  "info@example.com",
  "お問い合わせ (サイトから)",
  "お名前:\nご用件:\n"
);

本文の改行は、仕様では %0D%0A (CR と LF の 2 文字) で表します。JavaScript の文字列の改行はふつう LF (\n) だけなので、上の例では CRLF に直してから符号化しています。

空白は %20 になります。フォームの送信で使われる形式では空白を + で表しますが、mailto: では + は空白として扱われず、そのまま + の文字として件名に出てしまうことがあります。encodeURIComponent() は空白を %20 にするので、この点でも安心です。

なぜ文字化けが起きていたのか

以前の mailto: の仕様には、日本語のような ASCII 以外の文字を UTF-8 で符号化するという決まりがなく、扱いはブラウザーやメールソフトの実装に任されていました。そのため、次のような食い違いが起きていました。

  • ページが Shift_JIS などで書かれていると、ブラウザーがその文字コードのまま符号化したり、符号化せずに渡したりした
  • メールソフトの側も、受け取ったバイト列を UTF-8 と読むもの、OS の標準の文字コードと読むものがあった

書く側と読む側で文字コードの解釈がずれると、件名が意味のない文字の並びになります。当時は、ページの文字コードに合わせて符号化する、件名を英語にする、といった回避策が使われていました。

今は、ページを UTF-8 で作り、値を UTF-8 でパーセント符号化すれば、主なメールソフトやブラウザーの Web メールで正しく表示されます。それでも古いメールソフトでは化けることがあるので、公開前に、よく使われるメールソフトでいくつか試しておくと安心です。また、本文が長すぎると途中で切れることがあるため、本文には短いひな形だけを入れるのがよいでしょう。

迷惑メール対策と問い合わせフォームとの使い分け

mailto: リンクは手軽ですが、次のような弱点もあります。

  • ページの HTML にメールアドレスがそのまま載るため、アドレスを集めるプログラムに拾われ、迷惑メールが増えることがある
  • 利用者の端末でメールソフトが設定されていないと、何も起きなかったり、使っていないアプリが開いたりする

JavaScript でアドレスを組み立てて表示する方法は、単純な収集プログラムには効きますが、確実な対策ではありません。迷惑メールのフィルターと組み合わせて考えます。メールソフトが開かない場合に備えて、アドレスを文字でも書いておくと、利用者がコピーして使えます。

項目を決めて問い合わせを受けたい場合や、受け付けの記録を残したい場合は、問い合わせフォームのほうが向いています。フォームを作るときは、サーバー側で入力を確かめること、利用者の入力をメールのヘッダー (宛先や件名) にそのまま入れないこと (改行を混ぜて宛先を足される「メールヘッダーインジェクション」を防ぐ)、連続した送信を制限することなど、別の対策が必要になります。

まとめ

  • mailto: の件名や本文は、encodeURIComponent() で UTF-8 のパーセント符号化をしてから書く
  • 本文の改行は %0D%0A、空白は %20 で表す (+ は使わない)
  • ページは UTF-8 で作る。古いメールソフトでは化けることがあるので、公開前に試す
  • アドレスが収集されやすい点や、メールソフトが無い環境を考え、必要に応じて問い合わせフォームと使い分ける

参考