introducing guardMailto

The Problem

If you put something like this in your website:

<a href="mailto:test@example.com">email me!</a>

spammers can identify that test@example.com is an email address with automated tools that review thousands of websites (analogous to the “spiders” used by search engines like Google and Yahoo). They can add your address to their databases. And eventually, they will surely do so. In fact, it turns out that spammers are pretty good at extracting anything that looks like an email address, whether it’s in a mailto: link or not.

First Generation Solutions

There are already several libraries (and some commercial products) that use JavaScript to dynamically create mailto: links. I even wrote one myself a couple of years ago when I was providing web hosting for a number of small businesses.

The underlying theory is that while spammers could easily get your email address by going to the site, loading the page, and looking at the results, very few spammers will invest the time necessary to do so. If the automated tool doesn’t return an email address, they won’t check each site by hand. The economics of spamming are contingent on the incremental cost of sending each email being very, very low — anything that requires the spammer to invest time eats into the profit margin.

Most of these products used the principal of graceful degradation: If JavaScript was enabled in your browser, you got a functional email link. If JavaScript wasn’t available, you got alternate content provided in a <noscript> tag, if the page author provided it — or maybe nothing at all. Code for this approach — including my “munge” library — generally followed the following format:

A JavaScript library would be included in the <head> section of the document:

<script type="text/javascript" src="emailLib.js></script>

(Don’t worry if you’re not familiar with reading and writing JavaScript code. You don’t need to be a JavaScript expert to use guardMailto, and you can safely skip these examples.)

Then, in the body of the page, there would be some inline JavaScript that used document.write() to insert the link into the page:

<script type="text/javascript">
document.write(makeAnEmailLink("stringEncryptingEmailAddress"));
</script>

And, if you were lucky, there’d be a <noscript> tag that would provide a fallback for users without JavaScript:

<noscript>
email: test (at) example (dot) com
</noscript>

Towards a Second Generation Solution

I observed several serious problems with my “munge” library:

  • It was too complicated and hard to use. Programmers seemed comfortable with it, but web designers often weren’t, and “ordinary” people struggled mightily with it.
  • It was inflexible. It worked ok for text links that were all by themselves, but it didn’t readily support linking an image, for example.
  • It didn’t play particularly well with many “what-you-see-is-what-you-get” (WYSIWIG) web page editors.
  • It put the burden of creating the fallback <noscript> support on the page author. Many page authors were confused about how to do this effectively, and many just didn’t bother.

In the intervening time, I’ve learned a lot about object-oriented JavaScript, and I’ve become an advocate of progressive enhancement as an alternative to graceful degradation. (unobtrusive JavaScript is a related buzzword; I prefer “progressive enhancement” because it’s a design philosophy that’s applicable to more than just JavaScript.)

Progressive enhancement reverses the paradigm of graceful degradation: start with a basic html page that works “as-is,” and then enhance the functionality of the basic page for browsers that support it. Progressive enhancement makes it impossible to strand users of older browsers by omitting a <noscript> tag. It also better supports users who have a modern browser but may have JavaScript disabled or restricted for reasons of security and/or corporate policy. Finally, it often better addresses the accessibility needs of users with visual or other impairments.

Conceptually, the progressive enhancement model looks like this.

We still start with a library included in the <head> section:

<script type="text/javascript" src="emailLib.js></script>

In the body of the page, we have the link information in a format that is easily human-readable, but less easily machine-readable:

email me at <span id="contactAddress">test (at) example (dot) com</span>

And then we have some JavaScript that turns the human-readable text into a clickable link:

<script type="text/javascript">
makeAnEmailLink("contactAddress","stringEncryptingEmailAddress")
</script>

That JavaScript code can be inline in the page body, but it can also be somewhere else, so we can separate the page content from the presentation logic.

There’s one significant catch: You can’t turn the text into a link until after the browser has displayed it in the page. That makes this code a good candidate for an “onload” event, which the browser will run after the page finishes loading.

Enough Talk, Where’s the Code?

You can download either the raw javascript guardMailto.js or a gzip archive guardMailto.js.gz.

guardMailto is released under The MIT License.

Instructions for adding guardMailto to your site are covered in using guardMailto.

Leave a Reply