[javascript] Best way to obfuscate an e-mail address on a website?


Personally, I've given up on hiding my email address. I find it easier to look into better spam-filtering solutions than worry about obfuscating. You could spend days trying to find the best way to obfuscate your address, and then all it takes is one person to sell your address to a spammer and all that work was useless.


I've spent the past few days working on updating my personal website. The URL of my personal website is (my first name).(my last name).com, as my last name is rather unusual, and I was lucky enough to pick up the domain name. My e-mail address is (my first name)@(my last name).com. So really, when it comes down to guessing it, it's not very hard.

Anyways, I want to integrate a mailto: link into my website, so people can contact me. And, despite my e-mail address not being very hard to guess, I'd rather not have it harvested by spam bots that just crawl websites for e-mail address patterns and add them to their database.

What is the best way for me to obfuscate my e-mail address, preferably in link form? The methods I know of are:

<a href="mailto:x@y.com">e-mail me</a>

It works, but it also means that as soon as my website hits Google, I'll be wading through spam as spam bots easily pick out my e-mail address.

<img src="images/e-mail.png" />

This is less desirable, because not only will visitors be unable to click on it to send me an e-mail, but smarter spam bots will probably be able to detect the characters that the image contains.

I know that there is probably no perfect solution, but I was just wondering what everyone thought was best. I'm definitely willing to use JavaScript if necessary, as my website already makes use of tons of it.

<!-- Multi-Email Obfuscator  -->
<!-- step 1: &#064; = @  -->
<!-- step 2: a scrap element  -->
<!-- step 3: ROT13 encode for .com  -->
info<!-- step 1 -->&#064;<!-- step 2 --><b style="display:none">my</b>domain<!-- step 3 --><script>document.write(".pbz".replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);}));</script>

I don't how well this would work. Could you not leave your email address out and make it load using an AJAX call once the page has finished loading. Not sure if spam bots can pick up the altered HTML or if they are clever enough to listen on other HTTP traffic to try and pick email addresses or if they just scan the page as it is received the first time.

I use a PHP function to generate some javascript to output the email on page load. Note that you don't need PHP to generate the JS at runtime, you can generate the JS once locally and then include the static JS in your page.

You can also use the linked function with this snippet below to automatically obfuscate email addresses in some given HTML (where $processedContent is the HTML):

 $emailMatches = array();
 $matchCount = preg_match_all('/(?:[a-zA-Z0-9_\.\-])+\@(?:(?:[a-zA-Z0-9\-])+\.)+(?:[a-zA-Z0-9]{2,4})+/', $processedContent, $emailMatches);

 if($matchCount > 0) {
    $emailMatches = $emailMatches[0];

    foreach($emailMatches as $email) {
    $replacement = createJSMailLink($email);

    $processedContent = str_replace($email, createJSMailLink($email), $processedContent);

mine is actually simple:

<h3 id="email">hello@gmail.com</h3><!-- add a fake email -->

//my email in reverse :)
            var s = 'moc.elibomajninbew@htiek';
            var e = s.split("").reverse().join("");
            $('#email').html('<a href="mailto:'+e+'">'+e+'</a>');

Apparently using CSS to change the direction of your text works pretty well. That link has a test of a bunch of other obfuscation methods as well.

Whatever you use is inevitably going to be defeated. Your primary aim should be to avoid annoying the heck out of your users.

Another approach could be by using a JavaScript framework and binding the data/model to the HTML elements. In the case of AngularJS, the HTML elements would be written as:

<a href="mailto:{{contactEmail}}"><span>{{contactEmail}}</span></a>

The interpolation {{data}} binding uses a scope variable that contains the actual email value. In addition, a filter could also be used that handles the decoding of the email as follows:

<a href="mailto:{{contactEmail | decode}}"><span>{{contactEmail | decode}}</span></a>

The benefits are in the way the HTML is written. The downside is that it requires scripting support which some for may be a no no.

just another approach.

If you work with PHP, you can grab a free script that does that automatically. It's called "Private Daddy" and we use it for our own online audio streaming service. Just one line of code and it works out of the box... you can grab it here

Honestly, your problem may be moot if you asked the question of whether or not a mailto is really what you want to use. A lot of people who use web mail, for example, or do not have the proper mail client setup in their browser are not going to benefit from a mailto. You are exposing your email address for a function that isn't going to work for a large portion of your users.

What you could do instead is use a form to send the e-mail behind the scenes so that the e-mail address is hidden and you don't have to worry about the poor saps who won't benefit from a mailto.

You could do as Google do on Google Code (and Groups). Display a par tof the email, and a clickable portion ("..."). Clicking that indicates you want to know the email, and you are asked to fill in a captcha. Afterwards the email (and others?) are visible to you.

reCAPTCHA offers a simple email obfuscation service. You don't need to set up an account and can start using it immediately. You can use the service as a link or as a popup.

After the captcha is solved, your email address appears as an href/mailto, so that it can be clicked/followed by users who have configured their email clients to work with their browsers.

One website I maintain uses a somewhat simplistic JavaScript means of (hopefully) keeping spambots out.

Email links call a JS function:

function sendEmail(name, domain) {
    location.href = 'mailto:' + name + '@' + domain;

To make sure only users who have JS enabled can see the link, write them out with this:

function writeEmailLink(realName, name, domain) {
    document.write('<a href="javascript:sendEmail(\''
      + name + '\', \'' + domain + '\')">');

The use of one JS function to write out a link that calls another means that there are two layers of protection.