mailto: のスパム対策

ページにメールアドレスを書く必要に迫られてスパムメール対策について調べてみました。

調査結果

まあ一般的には下記の対策までのようです。というかサーバー側のフィルターが発達して、もう誰も気にしないのでしょうか・・・

  • 画像を使用する
  • アドレスをエンコードする
  • JavaScriptを使用する


しかし、JavaScritpを使用していてもアドレス収集RobotにWebKit等のエンジンを搭載してしまえば全然関係無い気がします(画像による対策はコピペしようとして騙された感があったりして今ひとつです)。

そんななかスパムメール対策(迷惑メール)実験室と言うページを見つけました(ここも2006年が最終更新のようですがorz)。このサイトで「3秒後に表示する」というアイデアが提示されていました。
確かに動的な要素まではRobotも相手にしなさそうです。このアイデアから着想を得て私もひとつスパム収集対策スクリプトを作成してみました。

mouseoverでmailtoを表示する

デモは追って用意しますが、実際に使用しているページがあります。そちらのコードを参照してください。
例えば最初は画像でメールアドレスを示しておいて、マウスを持っていくとmailtoへ変更します。画像アドレスでは無くメールアイコンにしておいて、マウスカーソルを重ねるとメールアドレスがスライドしてもかっこよいかもしれません(逆にうっとうしいか?)。
まずは、シンプルにmouseoverで切り替える方法です。

元の表示

本来はdivタグの中身を画像などにします。

<div id="to">to address</div>

入れ替えスクリプト

function showMT1(name, a) {
    a.m = ['m', 'a', 'i', 'l', 't', 'o', ':'].join('');

    var
    t = document.getElementById(name),
    l = document.createElement("a"),
    b = t.firstChild;

    t.onmouseover = append;

    function append() {
        var v = [a.n.join(''), a.d.join('')].join('@');

        l.style.display = 'block';
        l.href = a.m + v;
        l.firstChild && l.removeChild(l.firstChild);
        l.appendChild(document.createTextNode(v));
        t.replaceChild(l, t.firstChild);
        t.onmouseover = null;
        l.onmouseout = rm;
        return true;
    }
    function rm() {
        t.replaceChild(b, t.firstChild);
        t.onmouseover = append;
    }
}

どうでも良い事ですが、div要素の子要素をa要素に切り替えてしまうことでmouseoutmouseoverが発生して期待通りに動作しないため、一見すると冗長なコードになっています。
簡単にポイントを説明しておくと、まずurlエンコード自体はたいした効果がないようなので使用せず、JavaScriptの実行無しにはメールアドレスが特定できないように’@'との分離とアドレスの配列化を実施しています。
後は、DOMへのmailtoの書き出しを遅延することでスパムメール対策としています。

呼び出し

window.onload = function() {
    showMT1('to', { n: ['m', 'a', 'i', 'l'], d: ['a', 'd', 'd', 'r', 'e', 's', 's'] });
}

次にmouseoverでフェードイン、mouseoutでフェードアウトします(ここからはjQueryが必要になります)。

コード

function showMT(name, a) {
    a.m = ['m', 'a', 'i', 'l', 't', 'o', ':'].join('');
    var
    t = $('#' + name),
    b = t.html(),
    tid = -1,
    ak,
    ap = function () {
        if (ak && ak.css('display') != 'none') {
            tid != -1 && clearTimeout(tid);
            return;
        }
        var v = [a.n.join(''), a.d.join('')].join('@');
        ak = $('')
        .attr('href', a.m + v)
        .text(v)
        .hide()
        .fadeIn(function () {
            setTimeout(function () {
                ak.bind('mouseout', rm);
            }, 1);
        })
        .mouseover(function () {
            tid != -1 && clearTimeout(tid);
        });
        t.text('').append(ak);

        return true;
    },
    rm = function () {
        tid = setTimeout(function () {
            tid = -1;
            ak.fadeOut('normal', function () {
                t.html(b).remove('mouseout').one('mouseover', ap);
                ak.remove();
            });
        }, 2000);
    };
    t.one('mouseover', ap);
}

ここでの要点はmouseoutで元の画像へ戻ってしまうことをsetTimeoutを使用して遅延させていることです。
これはmouseoutですぐに画像に戻ってしまうとコピー&ペーストが出来なくて本末転倒になってしまうためです。
このためだけにかなり苦労してしまいましたが、そもそもmouseoutの処理は不要かもしれませんねorz

M. K. の紹介

IT屋さんです。プログラミングが大好きで今はJavascriptがお気に入りです。
カテゴリー: JavaScript, プログラミング   タグ: ,   この投稿のパーマリンク