Posté le 12 Juillet 2007 à 13:08
Vous le savez, il ne faut jamais laisser une adresse email en clair sur une page web si on ne veut pas qu'un spambot la repère et que sa boîte de réception soit envahie de spams en tout genres.EDIT (2010-10-10) : Allez aussi lire l'article de Gabriel Hautclocq.
Les solutions couramment utiliser pour contourner ce problème sont de remplacer le @ par [at], ou de mettre son adresse email sur une image par exemple.
Mais la première ne marche pas très bien : c'est facile de dire à un programme de détecter aussi bien les [at], _at_ et compagnie que les @.
Quand à la seconde méthode elle n'est pas pratique car il n'est du coup pas possible pour les visiteurs de copier-coller l'adresse email.
Une autre solutions est d'utiliser un JavaScript. C'est ce que j'ai fait jusqu'à maintenant. Mon adresse email n'apparait que dans dans un fichier .js et y est encodé en ROT13. Je l'affiche avec une fonction qui décode l'adresse sur le coup. Cette méthode viens du blog de Allan Odgaard.
Le code JavaScript de la fonction avec mon adresse email est :
→ Code : adresse email encodée en ROT13
1 2
3
4
function encoded_email (elem_id) {
var email = document.createTextNode("cnoyb.enhml@tznvy.pbz".replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);}));
document.getElementById(elem_id).appendChild(email);
}
La méthode des entités XML
Si vos pages sont en XHTML, et donc basée sur XML et non SGML, vous pouvez étendre un peu la DTD de XHTML pour y ajouter des entités.Une entité XML c'est quoi ?
Une entité XML est une sorte de raccourci vers une chaîne de caractère prédéfinie, il y en a déjà cinq de déclaré dans XML :<pour <>pour >&pour &"pour "'pour '
é pour é...).Et bien c'est ce que nous allons utiliser pour protéger notre adresse email. Une fois cette protection mise en place il suffira d'écrire
&contact; pour afficher notre adresse email avec un lien mailto: !Comment étendre la DTD de XHTML ?
Cela se fait au moment de la déclaration du DOCTYPE au début de votre fichier. Par exemple pour XHTML 1.1, le DOCTYPE est le suivant : → Code : DOCTYPE de XHTML 1.1
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
Une entité se déclare en utilisant la syntaxe suivante :
→ Code : syntaxe de déclaration d'une entité dans une DTD
1 <!ENTITY entity-name "entity-value">
&contact;.Par exemple pour moi ça donne :
→ Code : exemple de déclarations des trois entités
1 2
3
<!ENTITY myname "pablo.rauzy">
<!ENTITY gmail "gmail.com">
<!ENTITY contact "<a href='mailto:&myname;@&gmail;'>&myname;@&gmail;</a>">
Donc au final on a le code suivant :
→ Code : extension de la DTD
1 2
3
4
5
6
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
[
<!ENTITY myname "pablo.rauzy">
<!ENTITY gmail "gmail.com">
<!ENTITY contact "<a href='mailto:&myname;@&gmail;'>&myname;@&gmail;</a>">
]>
Et voilà le travail ! Maintenant il vous suffit d'utiliser l'entité
&contact; pour afficher un lien vers votre adresse email : &contact;.Ce lien s'affiche bien alors que j'ai juste écris
&contact;, vous pouvez le voir dans la source de la page (par contre comme une grosse partie est générée par PHP donc l'indentation du code est plus que foireuse :-p).Vous pouvez bien sûr utiliser cette technique pour plein d'autres choses.
&logo; pourrait afficher un petit logo, &truc; pourrait afficher un truc (si si !)... On peut aussi s'en servir pour les éléments de présentations : &separateur; pourrait être /, -, |, • selon votre humeur par exemple :-p. Un autre exemple d'utilisation tout bête : &message.info; affiche un message d'information qu'on peut modifier à un endroit seulement (la déclaration de l'entité) et qui sera automatiquement mis à jour partout sur le site :-)
Ombre :
Personellement, j'ai utilisé le code html suivant :
Avec ce script, pour le livre d'or du site de MamaCass. Ça a l'air de fonctionner. ;-)
Et c'est accessible aussi... ;-)
Par contre la phrase qui m'a fait quelque chose c'est , parce que (j'ai honte) je n'y avais pas du tout pensé, tout content que j'étais d'avoir trouvé cette méthode.
Ombre :
Sinon ta méthode est vraiment chouette, ça marche aussi avec xhtml 1.0 et l'envoi en text/html?
Ombre :
Pourquoi tu dis ça??? Elle est accessible ta méthode non? Quand j'ai dit ça je voulais dire que la méthode utilisée sur le livre d'or était accessible, comme la tienne. Rien de négatif donc. ;-)
Ou alors tu voulais dire que tu n'avais pas pensé à l'accessibilité? ;-)
Gabriel Hautclocq :
Ton astuce ne fonctionne pas sous internet explorer.
Pour les autres navigateurs que IE, il faut que la page soit servie en application/xhtml+xml (c'est à dire dans l'entête http elle même, voir la fonction header de php), pas seulement dans la balise meta.
Pour faire fonctionner cette astuce sous IE, il faut regarder l'exemple de ce site : http://www.informit.com/library/content.aspx?b=STY_XML_21days&seqNum=157
En fait il s'agit de faire un document xml important la dtd du XHTML (même principe qu'un bon vieux application/xhtml+xml de toute façon)
Mais du coup cela ne fonctionne plus pour Safari et Chrome. Quel casse tête...
Benoit Colin :
Je peux proposer une autre soluce, en combinant une image (pour avoir l'adresse mail en visuel), qui comporte un texte ALT pour les navigateurs restreints, et un coup de javascript pour orienter le clic vers un mailto:
Une démo est visible ici
Bon ouais c'est pas terrible :-D...
Je connaissais la solution de l'image, mais je ne trouve pas ça pratique car on ne peut pas sélectionner le texte ou un bout du texte :-/. Par contre c'est efficace ça c'est sûr :-).
Benoit Colin :
Hautclocq Gabriel :
Petite mise à jour : j'ai réussi à faire fonctionner l'astuce des entités sur tous les navigateurs. J'ai également trouvé un moyen d'obfusquer les liens dans un site (si l'on ne souhaite pas partager un lien par exemple) et par la même occasion un moyen d'utiliser ses propres balises en conjonction avec les balises XHTML usuelles (même les liens fonctionnent). Les extraits de code ci-dessous montrent comment utiliser les entités seulement, voir l'exemple complet pour les balises personnalisées.
La technique est somme toute assez simple :
1. La page web est un fichier .xml
2. Voici l'entête de ma page web de test :
Notez que je n'ai pas inséré le doctype XHTML. Ceci est intentionnel et nécessaire pour que cela fonctionne sous IE et évite des problèmes avec Webkit.
3. Cette page web est transformée par un processeur XSL en un autre document .xml au niveau client (pas serveur, sinon on perd l'intérêt de l'obfuscation) et affichée dans le navigateur. Voici un extrait de la feuille de style XSL :
<?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" media-type="application/xhtml+xml" omit-xml-declaration="no" encoding="utf-8" version="1.0" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" /> <!--basic xhtml structure--> <xsl:template match="/html"> <xsl:element name="html" namespace="http://www.w3.org/1999/xhtml"> <xsl:copy-of select="@*" /> <xsl:attribute name="xml:lang" namespace="http://www.w3.org/XML/1998/namespace">en</xsl:attribute> <xsl:apply-templates/> </xsl:element> </xsl:template> <!-- all tags --> <xsl:template match="//*"> <xsl:element name="{name()}" namespace="http://www.w3.org/1999/xhtml"> <xsl:copy-of select="@*"/> <xsl:apply-templates/> </xsl:element> </xsl:template> </xsl:stylesheet>Et le tour est joué :)
Pour un exemple complet, voir ici :
test.xml, test.xsl, test.css.
Voilà, en espérant que cela puisse servir.
Cordialement,
Gabriel Hautclocq
PS : le formatage du code ne fonctionne pas bien en utilisant les doubles crochets, donc j'ai mis le code entre balises [code][/code]. Je vous conseille de ne pas copier le code depuis le site mais depuis la source en exemple.
J'ai reformaté le code et mis des vrai lien vers les fichiers.
Gabriel Hautclocq :
J'ai mis à jour et expliqué ma méthode plus en détail à l'adresse suivante :
http://www.gabsoftware.com/tips/extending-xhtml-with-xml-xsl-transformations-entities-cdata-sections-javascript/
(c'est en anglais)
Crédit t'es bien entendu donné pour l'utilisation des entités XML en tant que moyen d'obfuscation des adresses email ;)
Dans la mise à jour, il n'y a par exemple plus besoin de préciser le namespace des éléments, ni de la première règle concernant /html.
Gabriel Hautclocq :
J'ai continué un peu mes recherches et j'ai été confronté à des problèmes avec... IE. Notament avec IE6 qui active le mode quirks si le préambule XML est présent et autres joyeusetés, et même avec IE9 beta qui fait de son mieux pour ne pas fonctionner avec ma méthode.
Je suis donc en train de mettre au point une autre méthode qui utilise toujours XSLT et permettrait de générer des emails facilement sans être obligé de les déclarer en tant qu'entités dans le DOCTYPE. Ça fonctionne déjà sur ce site : http://www.wilduniverse.org mais ce n'est pas documenté dans mon article pour l'instant. Cette solution est plus compliquée à mettre en œuvre et il faut utiliser PHP pour que ça fonctionne sur tous les navigateurs, mais je l'expliquerai lorsque j'aurai un peu de temps libre :).
En attendant, voici un extrait de ce qu'un robot spammeur verra dans ma page (pour un peu qu'il visite les fichiers XML):
ou encore
Pour plus de sécurité on peut même encoder chaque caractère en son entité XML en mixant mode décimal et hexadécimal au hasard (via une fonction écrite en PHP) :
Les lignes précédentes seront transformées en liens XHTML valides à l'aide d'une feuille de style XSL. La règle est la suivante :
<xsl:template match="//hiddenmail" priority="50"> <xsl:element name="a"> <xsl:attribute name="href"> <xsl:value-of select="concat('mailto:', @username, '@', @hostname, '.', @tld)"/> </xsl:attribute> <xsl:if test="@caption"> <xsl:attribute name="title"> <xsl:value-of select="@caption"/> </xsl:attribute> </xsl:if> <xsl:if test="@id | @class | @name"> <xsl:copy-of select="@id | @class | @name"/> </xsl:if> <xsl:choose> <xsl:when test="text()"> <xsl:value-of select="text()"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="concat(@username, '@', @hostname, '.', @tld)"/> </xsl:otherwise> </xsl:choose> </xsl:element> </xsl:template>Voilà je te tiendrai au courant lorsque mon article sera mis à jour :)
Note : les guillemets doubles ont été échappés par " dans mon post mais il ne faut bien entendu pas les échapper.