Closed. This question is opinion-based. It is not currently accepting answers.
Closed 1 year ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
When placing email addresses on a webpage do you place them as text like this:
joe.somebody#company.com
or use a clever trick to try and fool the email address harvester bots? For example:
HTML Escape Characters:
joe.somebody#company.com
Javascript Decrypter:
function XOR_Crypt(EmailAddress)
{
Result = new String();
for (var i = 0; i < EmailAddress.length; i++)
{
Result += String.fromCharCode(EmailAddress.charCodeAt(i) ^ 128);
}
document.write(Result);
}
XOR_Crypt("êïå®óïíåâïäùÀãïíðáîù®ãïí");
Human Decode:
joe.somebodyNOSPAM#company.com
joe.somebody AT company.com
What do you use or do you even bother?
Working with content and attr in CSS:
.cryptedmail:after {
content: attr(data-name) "#" attr(data-domain) "." attr(data-tld);
}
<a href="#" class="cryptedmail"
data-name="info"
data-domain="example"
data-tld="org"
onclick="window.location.href = 'mailto:' + this.dataset.name + '#' + this.dataset.domain + '.' + this.dataset.tld; return false;"></a>
When javascript is disabled, just the click event will not work, email is still displayed.
Another interesting approach (at least without a click event) would be to make use of the right-to-left mark to override the writing direction. more about this: https://en.wikipedia.org/wiki/Right-to-left_mark
This is the method I used, with a server-side include, e.g. <!--#include file="emailObfuscator.include" --> where emailObfuscator.include contains the following:
<!-- // http://lists.evolt.org/archive/Week-of-Mon-20040202/154813.html -->
<script type="text/javascript">
function gen_mail_to_link(lhs,rhs,subject) {
document.write("<a href=\"mailto");
document.write(":" + lhs + "#");
document.write(rhs + "?subject=" + subject + "\">" + lhs + "#" + rhs + "<\/a>");
}
</script>
To include an address, I use JavaScript:
<script type="text/javascript">
gen_mail_to_link('john.doe','example.com','Feedback about your site...');
</script>
<noscript>
<em>Email address protected by JavaScript. Activate JavaScript to see the email.</em>
</noscript>
Because I have been getting email via Gmail since 2005, spam is pretty much a non-issue. So, I can't speak of how effective this method is. You might want to read this study (although it's old) that produced this graph:
Have a look at this way, pretty clever and using css.
CSS
span.reverse {
unicode-bidi: bidi-override;
direction: rtl;
}
HTML
<span class="reverse">moc.rehtrebttam#retsambew</span>
The CSS above will then override the reading direction and present the text to the user in the correct order.
Hope it helps
Cheers
Not my idea originally but I can't find the author:
<a href="mailto:coxntact#domainx.com"
onmouseover="this.href=this.href.replace(/x/g,'');">link</a>
Add as many x's as you like. It works perfectly to read, copy and paste, and can't be read by a bot.
I generally don't bother. I used to be on a mailing list that got several thousand spams every day. Our spam filter (spamassassin) let maybe 1 or 2 a day through. With filters this good, why make it difficult for legitimate people to contact you?
Invent your own crazy email address obfuscation scheme. Doesn't matter what it is, really, as long as it's not too similar to any of the commonly known methods.
The problem is that there really isn't a good solution to this, they're all either relatively simple to bypass, or rather irritating for the user. If any one method becomes prevalent, then someone will find a way around it.
So rather than looking for the One True email address obfuscation technique, come up with your own. Count on the fact that these bot authors don't care enough about your site to sit around writing a thing to bypass your slightly crazy rendering-text-with-css-and-element-borders or your completely bizarre, easily-cracked javascript encryption. It doesn't matter if it's trivial, nobody will bother trying to bypass it just so they can spam you.
I think the only foolproof method you can have is creating a Contact Me page that is a form that submits to a script that sends to your email address. That way, your address is never exposed to the public at all. This may be undesirable for some reason, but I think it's a pretty good solution. It often irks me when I'm forced to copy/paste someone's email address from their site to my mail client and send them a message; I'd rather do it right through a form on their site. Also, this approach allows you to have anonymous comments sent to you, etc. Just be sure to protect your form using some kind of anti-bot scheme, such as a captcha. There are plenty of them discussed here on SO.
You can protect your email address with reCAPTCHA, they offer a free service so people have to enter a CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) to see your email: https://www.google.com/recaptcha/admin#mailhide
I've written an encoder (source) that uses all kinds of parsing tricks that I could think of (different kinds of HTML entities, URL encoding, comments, multiline attributes, soft hyphens, non-obvious structure of mailto: URL, etc)
It doesn't stop all harvesters, but OTOH it's completely standards-compliant and transparent to the users.
Another IMHO good approach (which you can use in addition to tricky encoding) is along lines of:
<a href="mailto:userhatestogetspam#example.com"
onclick="this.href=this.href.replace(/hatestogetspam/,'')">
If you have php support, you can do something like this:
<img src="scriptname.php">
And the scriptname.php:
<?php
header("Content-type: image/png");
// Your email address which will be shown in the image
$email = "you#yourdomain.com";
$length = (strlen($email)*8);
$im = #ImageCreate ($length, 20)
or die ("Kann keinen neuen GD-Bild-Stream erzeugen");
$background_color = ImageColorAllocate ($im, 255, 255, 255); // White: 255,255,255
$text_color = ImageColorAllocate ($im, 55, 103, 122);
imagestring($im, 3,5,2,$email, $text_color);
imagepng ($im);
?>
I know my answer won't be liked by many but please consider the points outlined here before thumbing down.
Anything easily machine readable will be easily machine readable by the spammers. Even though their actions seem stupid to us, they're not stupid people. They're innovative and resourceful. They do not just use bots to harvest e-mails, they have a plethora of methods at their disposal and in addition to that, they simply pay for good fresh lists of e-mails. What it means is, that they got thousands of black-hat hackers worldwide to execute their jobs. People ready to code malware that scrape the screens of other peoples' browsers which eventually renders any method you're trying to achieve useless. This thread has already been read by 10+ such people and they're laughing at us. Some of them may be even bored to tears to find out we cannot put up a new challenge to them.
Keep in mind that you're not eventually trying to save your time but the time of others. Because of this, please consider spending some extra time here. There is no easy-to-execute magic bullet that would work. If you work in a company that publishes 100 peoples' e-mails on the site and you can reduce 1 spam e-mail per day per person, we're talking about 36500 spam emails a year. If deleting such e-mail takes 5 seconds on average, we're talking about 50 working hours yearly. Not to mention the reduced amount of annoyance. So, why not spend a few hours on this?
It's not only you and the people who receive the e-mail that consider time an asset. Therefore, you must find a way to obfuscate the e-mail addresses in such way, that it doesn't pay off to crack it. If you use some widely used method to obfuscate the e-mails, it really pays off to crack it. Since as an result, the cracker will get their hands on thousands, if not tens or hundreds of thousands of fresh e-mails. And for them, they will get money.
So, go ahead and code your own method. This is a rare case where reinventing the wheel really pays off. Use a method that is not machine readable and one which will preferably require some user interaction without sacrificing the user experience.
I spent some 20 minutes to code off an example of what I mean. In the example, I used KnockoutJS simply because I like it and I know you won't probably use it yourself. But it's irrelevant anyway. It's a custom solution which is not widely used. Cracking it won't pose a reward for doing it since the method of doing it would only work on a single page in the vast internet.
Here's the fiddle: http://jsfiddle.net/hzaw6/
The below code is not meant to be an example of good code. But just a quick sample of code which is very hard for machine to figure out we even handle e-mails in here. And even if it could be done, it's not gonna pay off to execute in large scale.
And yes, I do know it doesn't work on IE = lte8 because of 'Unable to get property 'attributes' of undefined or null reference' but I simply don't care because it's just a demo of method, not actual implementation, and not intended to be used on production as it is. Feel free to code your own which is cooler, technically more solid etc..
Oh, and never ever ever name something mail or email in html or javascript. It's just way too easy to scrape the DOM and the window object for anything named mail or email and check if it contains something that matches an e-mail. This is why you don't want any variables ever that would contain e-mail in it's full form and this is also why you want user to interact with the page before you assign such variables. If your javascript object model contains any e-mail addresses on DOM ready state, you're exposing them to the spammers.
The HTML:
<div data-bind="foreach: contacts">
<div class="contact">
<div>
<h5 data-bind="text: firstName + ' ' + lastName + ' / ' + department"></h5>
<ul>
<li>Phone: <span data-bind="text: phone"></span></li>
<li>E-mail <span data-bind="visible: $root.msgMeToThis() != ''"><input class="merged" data-bind="value: mPrefix" readonly="readonly" /><span data-bind="text: '#' + domain"></span></span></li>
</ul>
</div>
</div>
</div>
The JS
function ViewModel(){
var self = this;
self.contacts = ko.observableArray([
{ firstName:'John', mPrefix: 'john.doe', domain: 'domain.com', lastName: 'Doe', department: 'Sales', phone: '+358 12 345 6789' },
{ firstName:'Joe', mPrefix: 'joe.w', domain: 'wonder.com', lastName: 'Wonder', department: 'Time wasting', phone: '+358 98 765 4321' },
{ firstName:'Mike', mPrefix: 'yo', domain: 'rappin.com', lastName: 'Rophone', department: 'Audio', phone: '+358 11 222 3333' }
]);
self.msgMeToThis = ko.observable('');
self.reveal = function(m, e){
var name = e.target.attributes.href.value;
name = name.replace('#', '');
self.msgMeToThis(name);
};
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
You can try to hide characters using html entities in hexa (ex: @ for #).
This is convenient solution, as a correct browser will translate it, and you can have a normal link.
The drawback is that a bot can translate it theorically, but it's a bit unusual.
I use this to protect my e-mail on my blog.
Another solution is to use javascript to assemble part of the address and to decode on-the-fly the address.
The drawback is that a javascript-disabled browser won't show your adress.
The most effective solution is to use an image, but it's a pain for the user to have to copy the address by hand.
Your solution is pretty good, as you only add a drawback (writing manually the #) only for user that have javascript disabled.
You can also be more secure with :
onclick="this.href='mailto:' + 'admin' + '#' + 'domain.com'"
One of my favorite methods is to obfuscate the email address using php, a classic example is to convert the characters to HEX values like so:
function myobfiscate($emailaddress){
$email= $emailaddress;
$length = strlen($email);
for ($i = 0; $i < $length; $i++){
$obfuscatedEmail .= "&#" . ord($email[$i]).";";
}
echo $obfuscatedEmail;
}
And then in my markup I'll simply call it as follows:
<a href="mailto:<?php echo myobfiscate('someone#somewhere.com'); ?>"
title="Email me!"><?php echo myobfiscate('someone#somewhere.com');?> </a>
Then examine your source, you'll be pleasantly surprised!
I wouldn't bother -- it is fighting the SPAM war at the wrong level. Particularly for company web sites I think it makes things look very unprofessional if you have anything other than the straight text on the page with a mailto hyperlink.
There is so much spam flying around that you need good filtering anyway, and any bot is going end up understanding all the common tricks anyway.
HTML:
<a href="#" class="--mailto--john--domain--com-- other classes goes here" />
JavaScript, using jQuery:
// match all a-elements with "--mailto--" somehere in the class property
$("a[class*='--mailto--']").each(function ()
{
/*
for each of those elements use a regular expression to pull
out the data you need to construct a valid e-mail adress
*/
var validEmailAdress = this.className.match();
$(this).click(function ()
{
window.location = validEmailAdress;
});
});
Spambots won't interpret this, because it is a lesser-known method :)
First, define the css:
email:before {
content: "admin";
}
email:after {
content: "#example.com";
}
Now, wherever you want to display your email, simply insert the following HTML:
<div id="email"></div>
And tada!
I use a very simple combination of CSS and jQuery which displays the email address correctly to the user and also works when the anchor is clicked or hovered:
HTML:
moc.elpmaxe#em
CSS:
#lnkMail {
unicode-bidi: bidi-override;
direction: rtl;
}
jQuery:
$('#lnkMail').hover(function(){
// here you can use whatever replace you want
var newHref = $(this).attr('href').replace('spam', 'com');
$(this).attr('href', newHref);
});
Here is a working example.
I don't bother. You'll only annoy sophisticated users and confuse unsophisticated users. As others have said, Gmail provides very effective spam filters for a personal/small business domain, and corporate filters are generally also very good.
The best method hiding email addresses is only good until bot programmer discover this "encoding" and implement a decryption algorithm.
The JavaScript option won't work long, because there are a lot of crawler interpreting JavaScript.
There's no answer, imho.
!- Adding this for reference, don't know how outdated the information might be, but it tells about a few simple solutions that don't require the use of any scripting
After searching for this myself i came across this page but also these pages:
http://nadeausoftware.com/articles/2007/05/stop_spammer_email_harvesters_obfuscating_email_addresses
try reversing the emailadress
Example plain HTML:
<bdo dir="rtl">moc.elpmaxe#nosrep</bdo>
Result : person#example.com
The same effect using CSS
CSS:
.reverse { unicode-bidi:bidi-override; direction:rtl; }
HTML:
<span class="reverse">moc.elpmaxe#nosrep</span>
Result : person#example.com
Combining this with any of earlier mentioned methods may even make it more effective
One easy solution is to use HTML entities instead of actual characters.
For example, the "me#example.com" will be converted into :
email me
A response of mine on a similar question:
I use a very simple combination of CSS and jQuery which displays the
email address correctly to the user and also works when the anchor is
clicked:
HTML:
moc.elpmaxe#em
CSS:
#lnkMail {
unicode-bidi: bidi-override;
direction: rtl;
}
jQuery:
$('#lnkMail').hover(function(){
// here you can use whatever replace you want
var newHref = $(this).attr('href').replace('spam', 'com');
$(this).attr('href', newHref);
});
Here is a working example.
Here is my working version:
Create somewhere a container with a fallback text:
<div id="knock_knock">Activate JavaScript, please.</div>
And add at the bottom of the DOM (w.r.t. the rendering) the following snippet:
<script>
(function(d,id,lhs,rhs){
d.getElementById(id).innerHTML = "<a rel=\"nofollow\" href=\"mailto"+":"+lhs+"#"+rhs+"\">"+"Mail"+"<\/a>";
})(window.document, "knock_knock", "your.name", "example.com");
</script>
It adds the generated hyperlink to the specified container:
<div id="knock_knock"><a rel="nofollow" href="your.name#example.com">Mail</a></div>
In addition here is a minified version:
<script>(function(d,i,l,r){d.getElementById(i).innerHTML="<a rel=\"nofollow\" href=\"mailto"+":"+l+"#"+r+"\">"+"Mail"+"<\/a>";})(window.document,"knock_knock","your.name","example.com");</script>
A neat trick is to have a div with the word Contact and reveal the email address only when the user moves the mouse over it. E-mail can be Base64-encoded for extra protection.
Here's how:
<div id="contacts">Contacts</div>
<script>
document.querySelector("#contacts").addEventListener("mouseover", (event) => {
// Base64-encode your email and provide it as argument to atob()
event.target.textContent = atob('aW5mb0BjbGV2ZXJpbmcuZWU=')
});
</script>
The only safest way is of course not to put the email address onto web page in the first place.
Use a contact form instead. Put all of your email addresses into a database and create an HTML form (subject, body, from ...) that submits the contents of the email that the user fills out in the form (along with an id or name that is used to lookup that person's email address in your database) to a server side script that then sends an email to the specified person. At no time is the email address exposed. You will probably want to implement some form of CAPTCHA to deter spambots as well.
There are probably bots that recognize the [at] and other disguises as # symbol. So this is not a really effective method.
Sure you could use some encodings like URL encode or HTML character references (or both):
// PHP example
// encodes every character using URL encoding (%hh)
function foo($str) {
$retVal = '';
$length = strlen($str);
for ($i=0; $i<$length; $i++) $retVal.=sprintf('%%%X', ord($str[$i]));
return $retVal;
}
// encodes every character into HTML character references (&#xhh;)
function bar($str) {
$retVal = '';
$length = strlen($str);
for ($i=0; $i<$length; $i++) $retVal.=sprintf('&#x%X;', ord($str[$i]));
return $retVal;
}
$email = 'user#example.com';
echo 'mail me';
// output
// mail me
But as it is legal to use them, every browser/e-mail client should handle these encodings too.
One possibility would be to use isTrusted property (Javascript).
The isTrusted read-only property of the Event interface is a Boolean
that is true when the event was generated by a user action, and false
when the event was created or modified by a script or dispatched via
EventTarget.dispatchEvent().
eg in your case:
getEmail() {
if (event.isTrusted) {
/* The event is trusted */
return 'your-email#domain.com';
} else {
/* The event is not trusted */
return 'chuck#norris.com';
}
}
⚠ IE isn't compatible !
Read more from doc: https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted
I make mine whateverDOC#whatever.com and then next to it I write "Remove the capital letters"
Another, possibly unique, technique might be to use multiple images and a few plain-text letters to display the address. That might confuse the bots.