jquery スパム対策 JavaScript/jQuery を使った迷惑メール対策

2013年6月4日

ウェブ上にメールアドレスを掲載すると、スパム(迷惑)メー「ルが届くようになることがあります。

迷惑メール(スパム)に使われるメールアドレスは、ロボット(自動巡回プログラム)によって自動収集されていて、ソースを分析し、メールアドレスのような文字列(@ や mialto が含まれたもの)を集めているようです。

以下はメールアドレス収集プログラムに収集されるのを防止する方法(スパム対策)の1つの例です。

追加情報

2013年6月4日に最初に掲載した方法は、かなり無駄が多かったので全面的に書き換えました。2015年8月29日

目次

メールアドレス用のリンク

メールアドレスをウェブ上に掲載する場合、a 要素を使ってリンク先として href 属性値に「mailto:」から始まる文字列を記述してメールアドレス用のリンクを作ることができます。(以下の方法でメールアドレスを掲載すると、スパムが来る可能性が高いです)

<a href="mailto:info@example.com">info@example.com</a>

info@example.com

表題(subject)付きのアドレスの場合は ?subject= を追加して以下のように記述します。

<a href="mailto:info@example.com?subject=お問い合わせ">info@example.com</a>

info@example.com

更に本文(body)も追加するには、以下のように記述します。

<a href="mailto:info@example.com?subject=件名&amp;body=本文">info@example.com</a>

info@example.com

以下のような書式になっています。

mailto:メールアドレス?subject=件名&amp;body=本文
  • ? … メールアドレスとその後の情報を ? で区切ります
  • subject= … メールの件名を記述します
  • body= … メールの本文を記述します
  • &amp; … 件名と本文を & マークで区切ります(文字参照の &amp; を使用します)

また、表示する文字をメールアドレス以外にする場合は以下のように記述できます。

<a href="mailto:info@example.com?subject=お問い合わせ">カスタマーサービス</a>

カスタマーサービス

しかし、上記の方法でメールアドレスを公開すると、HTML ソース中にメールアドレス(xxxx@xxx.xxx)を掲載することになり、また a 要素の href 属性に「mailto:」を記述していることからメールアドレスであることがわかってしまい、メールアドレス収集プログラムに簡単に収集されてしまい、結果としてスパムメールが来てしまいます。

JavaScript でメールリンクを生成(スパム対策)

JavaScript(jQuery)を使ってメールリンクを生成すると、HTML ソースや JavaScript ソースに直接メールアドレスは含まれないので、(自動収集プログラムが、単にファイルの中身を読むだけであれば)自動収集をある程度防ぐことができます。

以下は、件名や本文を含まない単純なメールリンクを生成する例です。

まず、HTML への記述の方法を決めておく必要がるので、以下のようなルールにします。

  • メールアドレスを表示する部分は span 要素で記述し、クラスを「nsm」(no spam mail の略)とすることとします(任意の値でかまいません)。
  • メールアドレスの「@」を半角英字のカンマ「,」に換えて記述します。
<!-- メールアドレスの記述 -->
<span class="nsm">info,example.com</span>

以下は、JavaScript(jQuery)を使ってメールリンクを生成する記述例です。

@ マークはそのまま記述せず、文字参照の &#64; を使用しています。

以下のスクリプトは外部ファイルとして保存して、読み込むようにします。

jQuery(function($){
  var delimiter = ",";  //分割文字をカンマに設定
  if($('span.nsm').length !== 0) { //メールアドレスがある場合のみ実行    
    if($('span.nsm').text() !== ''){
      var nsm_strings = $('span.nsm').text().split(delimiter);//分割文字で分割
      var pre = $.trim(nsm_strings[0]);  //最初の部分から空白を削除
      var domain = "&#64;" + $.trim(nsm_strings[1]);  
      //@(&#64;)と後ろの部分から空白を削除したものを連結
      var nsm_address =  pre + domain;    //メールアドレスを組み立てる
      $('span.nsm').html('<a href="ma' + 'ilto:' + nsm_address + '">' + nsm_address + '</a>');
    }
  }
});
  • split() メソッドは、指定された区切り文字(分割文字)で文字列を分割します。
  • $.trim() メソッドは、文字列の前後の空白を取り除きます。

同じページにメールアドレスが複数必要な場合は、each() メソッドを利用して以下のようにします。

jQuery(function($){
  var delimiter = ",";  //分割文字をカンマに設定
  if($('span.nsm').length !== 0) { //メールアドレスがある場合のみ実行 
    $('span.nsm').each(function() {
      if($(this).text() !== ''){
        var nsm_strings = $(this).text().split(delimiter);  //分割文字で分割
        var pre = $.trim(nsm_strings[0]);  //最初の部分から空白を削除
        var domain = "&#64;" + $.trim(nsm_strings[1]);  
        //@(&#64;)と後ろの部分から空白を削除したものを連結
        var nsm_address =  pre + domain;    //メールアドレスを組み立てる
        $(this).html('<a href="ma' + 'ilto:' + nsm_address + '">' + nsm_address + '</a>');
      }
    }); 
  }
});

表題(subject)付きや表示する文字をメールアドレス以外にする場合のスパム対策

表題(subject)付きや表示する文字をメールアドレス以外にする場合に対応させる方法です。まず、HTML への記述の方法を以下のように決めておきます。

  • メールアドレスを表示する部分は span 要素で記述し、クラスを「nsm」(no spam mail の略)とすることとします(任意の値でかまいません)。
  • メールアドレスの「@」を半角英字のカンマ「,」に換えて記述します。
  • 表題(subject)と表示する文字もそれぞれカンマ「,」で区切って表題、表示する文字の順番で記述します。

以下のように記述するようにします。

<span class="nsm">info, example.com, お問い合わせ, カスタマーサービス</span>

表題が不要な場合はその部分を空にしておきます。

<span class="nsm">info, example.com, , カスタマーサービス</span>

表示する文字と表題も不要な場合はメールアドレス部分をカンマで区切って記述します。

<span class="nsm">info, example.com</span>

以下がスクリプトの記述例です。同じページにメールアドレスが複数必要な場合にも対応しています。

jQuery(function($){
  if($('span.nsm').length !== 0) {
    $('span.nsm').each(function() {
      if($(this).text() !== ''){
        var nsm_strings = $(this).text().split(delimiter);  //分割文字で分割
        nsm_strings = $.map(nsm_strings, function(value){
          return $.trim(value);//分割した文字列から前後の空白を削除
        });       
        var pre = nsm_strings[0];  //アドレスの@マークの前の文字列
        var domain = "&#64;" + nsm_strings[1];  
        //@(&#64;)と後ろの部分を連結
        var nsm_address =  pre + domain;    //メールアドレスを組み立てる
        var addressWithSubject = nsm_address;
        if(nsm_strings[2]){    //表題が指定されていれば
          addressWithSubject += "?subject=" + nsm_strings[2];
        }
        if(nsm_strings[3]){   //表示する文字が指定されていれば
          $(this).html('<a href="ma' + 'ilto:' + addressWithSubject + '">' 
              + nsm_strings[3] + '</a>');
        }else{
          $(this).html('<a href="ma' + 'ilto:' + addressWithSubject + '">' 
              + nsm_address + '</a>');
        }   
      }
    }); 
  }
});

5行目:span 要素内の文字列を分割文字で分割して、それらの文字列の配列を変数に代入しています。

6行目~8行目:$.map() メソッドを使って、配列の要素(分割された文字列)の前後の空白を削除しています。

13行目:変数 addressWithSubject には、アドレス部分と表題部分になります。まずアドレス部分を代入しておきます。

14行目:もし表題が指定されていれば、nsm_strings[2] にその文字列が入っているはずです。その文字列が空白でなければ、addressWithSubject に表題の文字列を追加します。if 文で空白文字や null, undefined は false と判定されます。

17行目:表示する文字(nsm_strings[3])が指定されていれば、それを表示するようにしています。

21行目:表示する文字(nsm_strings[3])が指定されていなければ、メールアドレスを表示します。

クリッカブル・マップを使う場合のスパム対策

以下はクリッカブル・マップをクリックするとメールするようにした場合の例です。

この場合、メールリンクは area 要素の href に記述します。

メモ:クリッカブル・マップを作成する場合、img 要素の usemap 属性は map 要素の id(name) の値に「#」を付けて指定します。

<!-- クリッカブル・マップで特定のエリアをクリックすると href の値からメール送信するようにしたもの -->
<p id="contactphoto"><img src="../images/mail_photo.jpg" usemap="#contactMap" alt="メール送信用の写真"  />
<map id="contactMap" name="contactMap">
    <area alt="contact" href="info,example.com" coords="4,1,494,218" shape="rect">
</map>
</p>
var delimiter = ",";  //分割文字をカンマに設定
var nsm_strings = $('map#contactMap area').attr('href').split(delimiter);  //分割文字で分割
var pre = $.trim(nsm_strings[0]);
var domain = "&#64;" + $.trim(nsm_strings[1]);
var nsm_address =  pre + domain;  
//"&#64;"はHTML上では @ に変換されるがこの時点では"&#64;"のままなので @ に変換
$('map#contactMap area').attr('href', 'ma' + 'ilto:' + nsm_address.replace(/&#64;/, '@'));