How to spamproof a mailto link?
Asked Answered
S

10

64

I want visitors to be able to click on (or copy) an email address directly on my webpage. However, if I could make it (a little bit) harder for bots and other crawlers to get said email address and register it in a spam list, it would be awesome.

I found different ways of doing this (i.e. encoding mailto HTML links), either with JavaScript or in pure HTML, but what do you guys recommend ? The JavaScript techniques seem more complicated, but this may potentially affect users that have it turned off, and legit crawlers like Google.

On the other hand, the HTML one seems a bit basic, the bot writers should have figured it out by now...

Should I bother at all doing this, or will the spammers get my email anyway ? I know that antispam filters are getting better and better, but if I can do something more to slow spammers down, I will.

Selma answered 2/9, 2010 at 7:34 Comment(0)
T
46

JavaScript remains one of the best mailto obfuscator. For users with JavaScript disabled you may want to substitute the mailto link with a link to a contact form.

The following is a popular JavaScript anti spam email obfuscator:

There is also a php version of the above to be able to generate obfuscated emails from the server side.

This is the JavaScript code that the above tool would generate to obfuscate my email address (comments intact):

<script type="text/javascript" language="javascript">
<!--
// Email obfuscator script 2.1 by Tim Williams, University of Arizona
// Random encryption key feature by Andrew Moulden, Site Engineering Ltd
// This code is freeware provided these four comment lines remain intact
// A wizard to generate this code is at http://www.jottings.com/obfuscator/
{ coded = "[email protected]"
  key = "1DtzZ8TGBuhRjJMKWI4gkUF2qidfOyPmSN7X30Vpso6xvErLnwQCbalA95HcYe"
  shift=coded.length
  link=""
  for (i=0; i<coded.length; i++) {
    if (key.indexOf(coded.charAt(i))==-1) {
      ltr = coded.charAt(i)
      link += (ltr)
    }
    else {     
      ltr = (key.indexOf(coded.charAt(i))-shift+key.length) % key.length
      link += (key.charAt(ltr))
    }
  }
  document.write("<a href='mailto:"+link+"'>Email Me</a>")
}
//-->
</script><noscript><a href='contact-form.html'>Email Me</a></noscript>
Torsk answered 2/9, 2010 at 7:38 Comment(6)
This may be a stupid question, and I apologize for commenting/asking on such an old thread, but once the webpage is generated, the e-mail address seems to exist in plain text and you can right click, copy e-mail address. Wouldn't it be really simple for these spam bots to grab this information after it's decoded and displayed on the rendered page? I can't imagine it's that simple, but I just can't figure out what's preventing that and I'd very much like to know. Thanks! :)Frayda
In answer to the comment above, spam bots are VERY basic, they are designed to scan for HTML mailto links, obfuscation itself encodes the mailto link thus the spam bot cannot read it. It is unlikely there is a smart enough bot to decode this, as a smart bot would not be cost effective.Fimbria
I'm pretty sure that PhantomJS-based-bot would be able to read that email just fine.Russ
Correct - any headless browser kit will be able to read this link just fine. I'm afraid no client-side encryption or obfuscation will work against modern headless browser kit. If you want to keep your e-mail address from harvesting, provide a mail-form instead. Or just deal with the fact that it's going to get harvested, and get a mail server with good spam filtering - modern providers like GMail are smart enough to filter just about anything.Tripodic
the link is deadTeter
You can always decrypt only on a click event. Which makes it hard even for bots that render the page, because "they" need to know where to click.Patrilocal
M
22

This looks like a really cool method that encodes the characters, which I assume would defeat basic spam bots:

http://robspangler.com/blog/encrypt-mailto-links-to-stop-email-spam/

So

<a href="mailto:[email protected]">Email</a>

becomes

<a href="&#x6d;&#97;&#105;&#108;&#x74;&#111;&#58;&#116;&#101;&#115;&#116;&#x40;&#x74;&#101;&#115;&#x74;&#x2e;&#x63;&#111;&#109;">Email</a>

It's appealing in that it doesn't require any Javascript.

Plunker example here.

Moonset answered 21/2, 2017 at 14:7 Comment(5)
@beta please can you be more specific? It’s not working as a mailto, or it’s not defeating spambots? Which OS / browser versions? Did you try any others? It may be a platform-specific issue, which would be worthwhile knowing.Moonset
sorry, the script on the linked page (robspangler.com/blog/encrypt-mailto-links-to-stop-email-spam) is currently not working. it's not generating the obfuscated links.Angelesangelfish
This one seems to work to encode the email katpatuka.org/pub/doc/anti-spam.htmlMeltage
link dead here alsoTeter
I use ChatGPT to encode the email addressesOcana
M
19

Building on Daniel Vassallo's answer, one way to encrypt a mailto link that may avoid cleverer spambots that will evaluate JS document.writes (as pointed out by incarnate) would be to put the decryption in a Javascript function that is only evaluated when the link is clicked on. For example, using base64 as the "encryption":

<script>

  function decryptEmail(encoded) {

    var address = atob(encoded);
    window.location.href = "mailto:" + address;

  }

</script>

<a href="javascript:decryptEmail('dGVzdEB0ZXN0LmNvbQ==');">Email</a>

Working Plunker.

I don't claim to know whether this could or could not be outsmarted by a more sophisticated crawler.

Moonset answered 21/2, 2017 at 14:30 Comment(2)
This does seem like a simple and smart solution.Flameout
This should be the accepted answer. Also, if you use PHP you could simply use $encr_email = base64_encode($your_email); and then add the $enc_email variable to the href tag.Serg
C
12

You can use external services like aemail.com:

@email is a free e-mail hiding service that hides emails using short URLs redirecting senders to the mailto-url after clicking the link.

After entering an email at aemail.com, you will get a short URL, which can be used to replace your 'mailto' link. Once link is clicked, your user will be redirected to the 'mailto' URL without any notice of the aemail.com. API can be used to hide emails/get URLs dynamically.

Example:

<a href="mailto:[email protected]">Contact</a>

Replaced With

<a href="https://aemail.com/q2">Contact</a>

Will Keep Email Link Working.

Cathodoluminescence answered 22/5, 2017 at 7:58 Comment(0)
G
11

You could use the reCAPTCHA Mailhide functionality. This will render email addresses on the form [email protected] where the ellipsis is a link to view the full address. It is a little cumbersome for the visitor but should give premium protection. Having said that, this technique will not let your visitors copy the address directly from your webpage.

I don't get the part about the "legit crawlers" like Google. At least, I am unable to see why Google should index the email address anyway. (See OPs comment below.)

Giacometti answered 2/9, 2010 at 7:41 Comment(2)
For instance, they grab all sorts of info for the business listings in google maps. If possible, having the email address there would be great (I know that you can enter it manually, but I'm trying to find a reason ;)...).Selma
@Selma Ahhh, didn't think of that ... at all! Good one. And, yes, this renders the "Mailhide" strategy pretty useless.Giacometti
H
3

I simply use:

<script language="javascript" type="text/javascript">
var pre = "hideme";
document.write("<a href='mailto:" + pre + "@domain.com'>" + pre
+ "@domain.com</a>");
</script>
<noscript>Enable javascript to see our email!</noscript>
Heighttopaper answered 4/9, 2010 at 9:33 Comment(3)
Are you saying that BOTS cannot see any output from javascript, even if it is written into the html?Surveying
I'm not exactly sure about this but I could say it is better to use a similar method to protect your e-mail address.Heighttopaper
If you were to use this method, I would recommend wrapping the document.write in a setTimeout to delay it. Most 'humans' wouldn't notice the delay, but any bot that doesn't pause and just takes the initial html source won't get the address. i.e. setTimeout(function(){ document.write("<a href='mailto:" + pre + "@domain.com'>" + pre + "@domain.com</a>"); },250); This would delay the write for 250ms.Karnes
D
2

My version generates the link on the fly from a base64-encoded email string when the user hovers over the link, or if on a mobile device, touches it. All links with the attribute 'data-gen-email' will work.

// The string is your base64-encoded email
const emailAddress = atob("bWFpbHRvOnlvdUBkb21haW4uY29t");

// Select all links with the attribute 'data-gen-email'
const emailLinks = document.querySelectorAll('[data-gen-email]');

emailLinks.forEach(link => {
    link.onmouseover = link.ontouchstart = () => link.setAttribute('href', emailAddress);
});

You can encode your email to base64 by using btoa('mailto:[email protected]'), or elsewhere on the web:

btoa('mailto:[email protected]'); // "bWFpbHRvOnlvdUBkb21haW4uY29t"

Example link in html:

<a href="#" target="_blank" data-gen-email>Email Me!</a>
Discordance answered 27/11, 2019 at 22:16 Comment(0)
H
0
//This sets the mailto link when clicked. 
//As the link is followed, the focus is also lost and the link reset to # 
//html should look like this :
//<a class="courriel" data-courriel="john" data-objet="Just a test" href="#">Some text</a>

$('.courriel').click(function() { 
  var sA = $(this).attr('data-courriel'); // get nickname
  var sO = $(this).attr('data-objet');    // get subject
//Adresses are hard coded here; a nick name is used; 
//this to prevent having a potentially decypherable encoded adress  in the <a> tag
  switch (sA) { 
    case 'john': 
      $(this).attr('href', 'mailto:[email protected]?subject=' + sO);
      break;
    case 'paul':
      $(this).attr('href', 'mailto:[email protected]?subject=' + sO);
      break;
    default:
        $(this).attr('href', '#');
  }


})
$('.courriel').focusout(function() { //reset the link to # on focus loss
    $(this).attr('href', '#');
})
Hibbitts answered 3/6, 2020 at 16:11 Comment(0)
I
0

Full AntiSpam version

<div class="at">info<i class="fa fa-at"></i>google.com</div>
OR
<div class="at">info&#x40;google.com</div>

<style>
.at {
  color: blue;
  cursor: pointer;
}
.at:hover {
  color: red;
}
</style>

<script>
const el33 = document.querySelector(".at");
el33.onclick = () => {
  let recipient="info";
  let at = String.fromCharCode(64);
  let dotcom="google.com";
  let mail="mailto:";
  window.open(mail+recipient+at+dotcom);
}
</script>
Infanta answered 15/12, 2022 at 6:57 Comment(0)
B
0

This is what I use. I don't know where I found it. I'm not javascript savvy at all so needed the "Javascript for Dummy's" version. :-) Wish I knew how to make it pre-fill in a subject line. Someday...maybe.

<script language=javascript>var name = "firstname.lastname@";
document.write ("<a href=\"mailto:" + name + "gmail.com\">John Doe</a>");</script>

Result: [email protected]

Broadminded answered 16/6 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.