I'm creating a new website, so I am thinking about how to protect my email address and phone number against crawlers, I actually mean email harvesters (most of which I suppose don't have JavaScript enabled, but I don't have any proof of it). What I do now is definitely security by obscurity or obfuscation (I might be confusing the two terms), as I want the email address to be normally visible and clickable by the user.

I started with resurrecting my 10+ years old code and editing it a little. The basics remain the same as 10+ years ago when I first coded this principle.

My question for Code Review SE - as I already posted Is this a valid option? in Security SE question - is rather clear. Primarily, I am interested in a review of this piece of code:

HTML part

<span id="m_link">test [a.t] example [d.o.t] com</span>
<span id="t_link">+444 444 6[eight]6 6[eight][eight]</span>

JavaScript part

function fix_m_link()
    var item1 = '@'; var item2 = '.'; var m_clear_text = 'test' + item1 + 'example' + item2 + 'com';
    document.getElementById('m_link').innerHTML = '<a href="mai' + 'lto:' + m_clear_text + '">' + m_clear_text + '</a>';

function fix_t_link()
    var item8 = '8'; var t_with_spaces = '444 6' + item8 + '6 6' + item8 + item8; var t = t_with_spaces.replace(/\s+/g, '');
    document.getElementById('t_link').innerHTML = '<a href="tel:+444' + t + '">' + '+444 ' + t_with_spaces + '</a>';

These functions I then call in the body's onload.


First of all, ES2015+ onwards have template literals forw easier interpolation of string and data. For instance:

function fix_m_link(){
  var item1 = '@'
  var item2 = '.'
  var m_clear_text = `test${item1}example${item2}com`
  document.getElementById('m_link').innerHTML = `<a href="mailto:${m_clear_text}">${m_clear_text}</a>`

Also, JavaScript uses camel case for naming. So you might want to change fix_m_link and m_clear_text.

Putting code in one line makes it hard to read. If you have a build step, let a minifier do this. If the code is very short (like in your question), the extra kilobytes saved from omitted newlines is not worth making the code unreadable. Write code for humans to read.

Now if you really want to obscure your email, use a contact form instead. Some CMSes support this out of the box. And if your site is static, there are third-party services that allow you to embed a contact form. Most of them also support captchas, which will deter automated form submissions.

| improve this answer | |

Template literals

Thanks to Joseph's answer about template literals, much appreciated, and implemented.

Immediately Invoked Function Expression

Immediately Invoked Function Expression is used here to bypass my Content Security Policy, as no inline scripts - like I had in the body's onload - are allowed now.

Readability - goodbye long lines

It's imperative for new script readers (and the owner too) to have a clean-looking in front of their eyes for the code to be easily maintained. Thus, an enhancement has been implemented in the form of line breaks.

Obfuscation (like mail: + tel: gone, hexa chars, etc.)

The script contains no texts as whole for crawlers to grep for now.

Not only the mail: and tel: are gone, split in pieces; more importantly, some key characters have been encoded into hexadecimal codes and are being converted on-the-fly.


Regarding the camelCase, it is established in JavaScript, so I implemented it into the script.

Re-written code

I was now able to tweak my script as follows:

( function fixEmlLink ()

    var itemX = String.fromCharCode(parseInt('0x40'));
    var itemY = String.fromCharCode(parseInt('0x2e'));

    var emlClearText = `info${itemX}example${itemY}com`;

    document.getElementById('eml_link').innerHTML =
        '<a href="mai' + `lto:${emlClearText}">${emlClearText}</a>`;

} () );

( function fixPhnLink ()

    var itemX = String.fromCharCode(parseInt('0x37'));
    var itemY = String.fromCharCode(parseInt('0x30'));

    var phnWithSpace = `${itemX}${itemX}8 8${itemY}8 8${itemY}${itemY}`;
    var phnClearText = phnWithSpace.replace(/\s+/g, '');

    document.getElementById('phn_link').innerHTML =
        '<a href="te' + `l:+88${itemY}${phnClearText}">+88${itemY} ${phnWithSpace}</a>`;

} () );
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.