Le fichier htaccess

Openweb.eu.org > Articles  > Le fichier htaccess

Abstract

Dans la trousse à outils des métiers du Web se trouve un formidable outil nommé le fichier .htaccess. Souvent sous-estimé et traité trop rapidement, ce dernier vous propose pourtant un panel de possibilités incroyablement riche.

Article

Les fichiers .htaccess sont des fichiers de configuration du serveur Apache, le serveur le plus répandu sur le Web. Ils se présentent sous la forme suivante : un simple fichier nommé .htaccess (pas d’extension, juste le nom « htaccess » avec un point au début pour le cacher sur Linux).

Ils ont beaucoup de possibilités qui vous permettront d’améliorer vos sites, que ce soit pour l’ajout de nouvelles fonctionnalités, pour l’expérience utilisateur, le SEO, les performances Web, etc.

Ils vous permettront même parfois de simplifier la vie du développeur et de lui faire gagner de la productivité. Autrement dit, tout ce qu’il faut pour « bien faire le web », selon la formule consacrée d’Openweb.

Attention, certaines propriétés de ces fichiers peuvent être extrêmement puissantes et, à la moindre erreur de syntaxe, le serveur répondra à toute demande par une erreur 500. Testez vos modifications sur un serveur de développement, utilisez les propriétés à bon escient et avec toute la prudence nécessaire !

Voici un petit inventaire non exhaustif.

Types MIME, spécification du codage (charset)

Il peut arriver que les types MIME (les identifiants de formats de données) ne soient pas définis par défaut dans la configuration du serveur. Cela peut poser problème si le serveur n’envoie pas correctement ces identifiants de formats de données au navigateur, qui peut se retrouver incapable de comprendre ce que représentent ces données.

Un exemple typique : la balise vidéo introduite récemment avec HTML5 nécessite que le serveur indique les bons identifiants des formats des fichiers vidéo, à savoir mp4, webm, et ogg.

Dans ce cas, le fichier .htaccess peut aisément résoudre ce problème :

AddType video/ogg ogv
AddType video/mp4 mp4 m4v f4v f4p
AddType video/webm webm

Un autre aspect rendu possible par le fichier .htaccess est d’indiquer le codage de certains fichiers. Dans changer de jeu de caractère pour UTF-8, nous indiquions comment le faire :

AddDefaultCharset UTF-8
AddCharset UTF-8 .html .css .js

Dans cet exemple, les fichiers dont les extensions sont .html,.css, .js seront envoyés avec un en-tête indiquant le codage UTF-8 (assurez-vous que tout le monde travaille bien en UTF-8 dans l’équipe, et vérifiez également les plugins récupérés ici ou là).

Pages d’erreurs personnalisées

Autre possibilité du fichier .htaccess, il est possible de spécifier les pages d’erreurs personnalisées, les plus courantes sont l’erreur 404 (contenu introuvable), l’erreur 403 (accès interdit) et l’erreur 500 (erreur interne au serveur).

ErrorDocument 404 /404.html
ErrorDocument 403 /403.html
ErrorDocument 500 /500.html

Cela vous permet d’afficher une page d’erreur d’apparence bien plus amène que les pages d’erreur par défaut du serveur quand les visiteurs arrivent au mauvais endroit ou au mauvais moment.

Redirections/réécriture d’URL

Redirections

Ne laissez pas vos visiteurs et les robots d’indexation se casser le nez sur l’ancienne adresse d’une page déplacée lors d’une refonte : redirigez-les vers la nouvelle adresse.

Dans ce cas, il suffit de mettre en place des redirections permanentes dans le fichier .htaccess (également appelées redirections 301). Ces redirections ont l’avantage de s’effectuer côté serveur, d’être mises en cache par les navigateurs et d’être transparentes pour les utilisateurs.

Exemple :

RedirectPermanent /ancienne-page.php http://www.monsite.com/nouvelle-page.php

Ainsi toute requête de la page /ancienne-page.php sera redirigé vers www.monsite.com/nouvelle-page.php.

Réécriture d’URL

Un autre aspect est la réécriture des URLs, cela permet de les simplifier et de les rendre plus intelligibles, que ce soit pour les visiteurs ou encore une fois pour les moteurs de recherche.
Plutôt qu’un long discours, prenons un simple exemple :

RewriteEngine on 
RewriteRule ^(.*)-([0-9]+)\.html ./detail.php?id=$2 [L]
# tout ce qui commence par (n'importe quoi)-(un nombre).html

permettra à votre site de comprendre que l’adresse www.monsite.com/un-nom-bien-descriptif-1337.html doit être interprétée ainsi www.monsite.com/detail.php?id=1337.

Réécriture d’URL, des possibilités infinies

Ces deux possibilités – redirections et réécriture – sont « combinables », cela offre de formidables solutions à de nombreux problèmes potentiellement très chronophages, en voici quelques exemples :

RewriteRule  ^ancien_dossier/(.*)$  ./nouveau_dossier/$1 [R=301,L]

Cet exemple permet de rediriger toutes les requêtes vers des fichiers dans ancien_dossier vers nouveau_dossier en conservant le nom de fichier. Par exemple : www.monsite.com/ancien_dossier/test.html sera redirigé vers www.monsite.com/nouveau_dossier/test.html.

Vous aurez noté le [R=301,L] à la fin de la ligne. Ce sont des drapeaux (flags) de réécriture. Ils ajoutent des directives à la réécriture, dans notre exemple, le R=301 indique que la réécriture est une redirection permanente. Le L (comme Last, dernier en anglais) indique que le serveur n’a pas besoin de lire les autres règles si celle-ci est satisfaite.

Réécriture avec transmission des chaines de requêtes

RewriteRule /pages/(.+) /page.php?page=$1 [QSA] 

Avec le drapeau [QSA], une requête pour /pages/123?one=two sera réécrite en /page.php?page=123&one=two. Sans le drapeau [QSA], la même requête sera réécrite en /page.php?page=123 - autrement dit, la chaîne de requête (query string) existante sera supprimée.

Note : de très nombreux drapeaux existent, pour approfondir le sujet, vous pouvez consulter la liste complète des drapeaux de réécriture.

Redirection des noms de domaine

RewriteCond %{HTTP_HOST} ^www.monsite.org
RewriteRule ^(.*)$ http://www.monsite.com/$1 [R=301,L]

Cet exemple permet de rediriger de manière permanente toute requête sur www.monsite.org/ vers www.monsite.com/ (typiquement lors d’un changement de nom de domaine, en supposant que les noms de domaines pointent vers le même serveur). Bien sur, la condition est assurée par rewritecond.

Performances Web

Mise en cache

Le fichier .htaccess permet également de spécifier la mise en cache des contenus ainsi que la compression des fichiers. Dans l’article sur les performances web avancées, nous avions cet exemple pour la mise en cache :

<FilesMatch "\.(js|css|gif|jpg|jpeg|png|ico)$">
Header unset Cookie
Header unset Set-Cookie

Header set Cache-Control "max-age=31536000"

Header set vary  "Accept-Encoding"
Header append vary "User-Agent"
Header append Cache-Control "public" 

Header append Connection "Keep-Alive"
Header append Keep-Alive "timeout=5, max=100"

FileETag None
</FilesMatch>

Dans notre exemple, Header unset Cookie et Header unset Set-Cookie permettent d’éviter la gestion des cookies pour ces fichiers statiques (qui peuvent amener des requêtes HTTP inutiles).

Header set Cache-Control "max-age=31536000" gère le contrôle du cache : les éléments sont mis en cache pour une année (le nombre correspond à une année en secondes), c’est-à-dire que le cache est valide une année durant.

Header set vary "Accept-Encoding" : Cette instruction indique aux proxies de mettre en cache deux versions de la ressource : une compressée, et une non compressée. Ainsi, cela donne la possibilité aux proxies de proposer les deux versions, selon ce que l’utilisateur demande.

Les deux lignes concernant le Keep-Alive permettent d’activer les connexions persistantes, c’est-à-dire de laisser la connexion ouverte au cas où le navigateur ait d’autres requêtes (ce qui économise des requêtes TCP/IP). Attention, si cela améliore les performances pour le client, cela peut faire consommer des ressources et surcharger le serveur… Et donc impacter les performances. En général, il est recommandé de régler cette option sur un serveur de fichiers statiques.

FileETag None : les Etags ne seront pas utilisés, la mise en cache est correctement assurée par le Cache-Control.

Compression

Quant à la compression, voici un exemple très simple :

AddOutputFilterByType DEFLATE text/text application/xml application/xhtml+xml text/html text/javascript text/css text/plain

Cette ligne un peu cryptique indique au serveur de compresser les contenus à base de texte (XML, XHTML, HTML, JS, CSS, etc) avant de les envoyer. Ces différents types de fichiers sont bien plus rapide à transférer quand ils sont compressés, et ils arrivent donc bien plus vite au navigateur qui les demande. Si en plus vous autorisez le navigateur à le garder en cache, le gain en performance est considérable.

Conséquences de la mise en cache

La mise en cache des fichiers dits « statiques » peut poser un problème : si le fichier est mis à jour, les internautes ayant déjà mis en cache les fichiers ne verront pas les changements, cela peut être particulièrement problématique pour la CSS ou pour les fichiers JavaScript.

La première idée serait d’appeler la CSS ainsi :

<link rel="stylesheet" href="/style.css?v=4" />

La mise en cache se ferait sur style.css?v=4, et donc il n’y aurait qu’à changer le numéro pour faire comprendre qu’une nouvelle version est à mettre en cache. Cette phrase est au conditionnel, car cette technique pose des problèmes sur les proxies, il est donc conseillé d’indiquer la version dans le nom de fichier (ce qui forcerait à le renommer à chaque fois).

Cela pourrait être gênant à gérer, mais encore une fois, la réécriture nous solutionne élégamment le problème :

RewriteRule ^(.+)_(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L]

Avec cette réécriture, le fichier CSS appelé ainsi :

<link rel="stylesheet" href="/style_20120909.css" />

sera réécrit en style.css. Le JavaScript appelé via javascript_20110806.js sera réécrit en javascript.js.

Sécurité, restriction d’accès

Le fichier .htaccess peut vous permettre de restreindre l’accès à certains répertoires, fichiers, etc. et d’améliorer certains aspects de sécurité de vos sites. Voici quelques exemples basiques de ces possibilités.

Si ce .htaccess contient ceci :

Order allow,deny
Deny from all

l’accès au dossier dans lequel il est sera purement et simplement interdit. Si vous souhaitez que l’accès soit possible, mais que l’affichage du contenu du répertoire soit interdit :

Options -Indexes

Cette directive déclenchera une erreur 403 si quelqu’un essaie de lister un répertoire, par exemple www.monsite.com/images/.

Il est également possible de restreindre/interdire l’accès à une IP ou à une plage d’IP :

Order deny,allow
Deny from all 
# interdit à tout le monde sauf
Allow from 123.45.6.7
Allow from 13.37
# Toutes les adresses IP commençant par 13.37

Il est également possible de restreindre l’accès à un login/mot de passe. Cela se fait avec un fichier .htpasswd (qui contient les logins/mots de passe), et le cas échéant avec un .htgroup (qui contient les groupes d’utilisateurs autorisés) :

AuthUserFile /home/chemin/var/www/chemin_vers_htpasswd/.htpasswd
# les logins et mots de passe 
AuthGroupFile /home/chemin/var/www/chemin_vers_htgroup/.htgroup
# les groupes d'utilisateurs
AuthName "Administrator required"
AuthType Basic
<Limit GET POST>
require group admin
# seul le groupe admin est autorisé
# peut être remplacé par 
# Require valid-user
# s'il n'y a pas de gestion de groupes

</Limit>

Comme vous pouvez le constater, l’appel aux fichiers .htpasswd et .htgroup doit se faire avec un chemin absolu, comprenez le chemin depuis la racine du serveur (aussi appelé le chemin canonique absolu).

Ce chemin absolu se détermine par exemple avec la fonction PHP realpath(), qui utilisée dans un dossier, vous indiquera le chemin absolu vers ce dernier. Si vous la mettez dans un fichier PHP nommé test.php :

<?php
echo realpath('test.php'); 
// résultat => /home/site/www/dossier_protege/test.php
?>

Cet exemple utilisera donc le fichier .htpasswd suivant :

mon_login:$1$HcqHtQCI$uRN/iIRjm2tdS1HwDFmpV0

Le login est donc « mon_login », le mot de passe correspondant est crypté. Vous pouvez le crypter en utilisant la fonction crypt de PHP :

<?php
echo crypt('toto'); 
// donnera $1$HcqHtQCI$uRN/iIRjm2tdS1HwDFmpV0 
?>

Quand au fichier .htgroup, il contiendra simplement les groupes d’utilisateurs :

admin:mon_login autre_login
users: jean jacques goldman

Dans notre exemple, seuls les logins « mon_login » et « autre_login » font partie du groupe « admin », ils seront les seuls à pouvoir avoir accès au dossier protégé par le .htaccess.

Autre exemple qui va faire écho au précédent, si dans un dossier vous avez un dossier qui ne doit contenir que des images, vous pouvez interdire l’exécution de fichiers comme PHP :

<FilesMatch "\.(pl|cgi|py|php|php3|php4|php5|phtml?|shtml?)$">
Deny from all
</FilesMatch>

L’idée est donc de protéger les fichiers .htaccess, htpasswd ainsi que htgroup, toujours selon le même principe :

<FilesMatch "\.(htaccess|htpasswd|htgroup)$">
Deny from all
</FilesMatch>

Normalement, les bons hébergeurs le font déjà pour vous, mais pensez à vérifier que vos fichiers sensibles ne soient pas lisibles depuis un simple navigateur, vous éviterez d’avoir des surprises. Dans le même esprit, il est de bon ton de restreindre l’accès à certaines sources :

<DirectoryMatch .*\.(svn|git|hg|bzr|cvs)/.*>
Deny From All
</DirectoryMatch>

Cela peut éviter ce genre de mésaventures : 3300 sites très fréquentés ont une faille basique de sécurité (lien en anglais).

Ajout : attention, à partir de la version 2.4 d’Apache, cette syntaxe change légèrement. Vous pouvez voir ces changements de syntaxe ici : Nouveaux mécanismes d’authentification.

Conclusion

C’est un petit arsenal que le fichier .htaccess nous offre : il intervient sur beaucoup de points de la qualité Web et permet de les résoudre simplement, élégamment et durablement.

Une fois n’est pas coutume, il est impossible d’être exhaustif sur le sujet. Nous vous invitons à étudier les liens donnés en référence ci-dessous, ces derniers fourmillent de bonnes idées, d’améliorations et d’informations sur le sujet.

Ainsi, vous pourrez vous construire votre propre trousse à outils selon vos besoins et améliorer la qualité de vos sites Web !

A noter : à chaque fois qu’un fichier est demandé au serveur, il doit lire tout le contenu du fichier .htaccess. Faites donc régulièrement le ménage dedans (les redirections en particulier n’ont pas vocation à rester éternellement). Si vous pouvez modifier la configuration du serveur, il vaut mieux placer toutes les règles génériques dans le fichier vhost.conf qui n’est lui chargé qu’au démarrage du serveur, vous lui éviterez des traitements inutiles.

Références, annexes

À propos de cet article

  • Openweb.eu.org
  • Profil : Expert
  • Thème : Industrialisation, Qualité
  • Auteur :
  • Publié le :
  • Mise à jour : 9 mars 2017
  • 26 commentaires

Vos commentaires

  • Zougane HAFFEZ Le 9 octobre 2012 à 13:23

    Bonjour, merci pour cette article qui liste certaine fonctionnalité du fichier .htaccess Pour ma part, je m’en sert souvent et c’est vraiment puissant.

  • Grégoire Noyelle Le 13 novembre 2012 à 07:05

    Merci pour cet article très complet. Je suis également fan de ces commandes. Voici un très bon livre sur le sujet par Jeff Starr : http://htaccessbook.com/

  • Jeromeweb Le 13 novembre 2012 à 17:39

    Le fichier .htaccess est une fonctionnalité d’Apache qui est très utilisée en SEO.
    Je vous conseille, d’expérience, de toujours faire une backup de l’ancien avant toute modification, car comme évoqué dans cet article, tout votre site peut être down après...
    Après une nouvelle mise en production, je vous conseille de regarder les logs d’Apache, ils vous fournissent certaines erreurs qui ne sont pas forcément visibles du navigateur

  • Raoul Le 13 novembre 2012 à 18:21

    Il manque peut être des structures conditionnelles pour que les modules absents ou que l’on désactive pour une raison X ou Y ne bloquent pas le site avec une belle erreur 500.
    Par exemple pour les caches des fichiers médias :

    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            <FilesMatch "\.(js|css|gif|jpg|jpeg|png|ico)$">
                Header set Cache-Control "max-age=31536000"
                [...]
            </FilesMatch>
        </IfModule>
    </IfModule>
  • Nicolas Hoffmann Le 14 novembre 2012 à 20:43

    Raoul : oui, je les ai limités pour de simples raisons de lisibilité des exemples. :)

  • Wissem Halibi Le 21 novembre 2012 à 06:23

    Peut on limiter l’accès à plusieurs répertoires par des logins propres à chacun et ceux en utiliser un seul fichier .htaccess ?

  • Prélude Le 22 novembre 2012 à 15:29

    Et, lorsque cela est possible, pour des raisons de performance, il est préférable de faire toutes ces jolies ligne de codes dans le fichier de configuration d’Apache plutôt que dans le fichier htaccess qui sera interprété à chaque requête.

  • Antoine Le 3 décembre 2012 à 16:33

    Attention également à bien uploader un htaccess sur la aprtie assets si ceux si sont hébergés sur un sous domaine. En effet, en voulant optimiser la perf en utilisant un domaine en parallèle, on peut réduire cela à néant en oubliant simplement de mettre en cache les ressources sur celui-ci.
    Pour le reste, merci pour tous les conf que tu donnes. Si plus de personnes connaissaient cette syntaxe "Order allow,deny, Deny from all", le téléchargement de fichiers sons et vidéos serait plus compliqué ;)
    Cordialement

  • Arthur Le 3 février 2013 à 17:30

    Merci pour ces précisions, articles très complet je trouve qui arrive à couvrir toutes les fonctions "basiques" (et plus) d’un fichier .htaccess ; je m’en suis servi pour compléter mes informations et pouvoir faire une meilleure présentation et vulgarisation.

    Et merci aux personnes laissant des commentaires qui laissent ainsi de nouvelles pistes de réflexions ou d’autres précisions.

  • Belkawired Le 17 avril 2013 à 11:24

    je cherchais justement des infos sur le fichier htaccess, ça a répondu à quelques erreurs que j’ai fait. Merci pour les infos !

  • philippe Le 17 septembre 2013 à 19:53

    merci pour votre article qui vient de me sortir d’une semaine de galère !

  • Nicolas Hoffmann Le 12 novembre 2013 à 11:48

    Je complète l’article :

    <FilesMatch "(?<!\.png|\.jpg|\.gif|\.jpeg|\.svg|\.ico)$">
     deny from all
    </FilesMatch>

    permet d’interdire tout autre fichiers que ceux mentionnés en extension.

  • Kilroy Le 2 décembre 2013 à 14:56

    Excellent article : une bonne source d’info à bookmarker.

    Un autre article sur la gestion des temps de chargements et le .htaccess que j’avais trouvé intéressant : http://www.seomix.fr/guide-htaccess...

    Sinon, on peut aussi utiliser le .htaccess pour interdire le hotlinking.

    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http://(www\.)?monsite\.tld/.*$ [NC]
    RewriteRule \.(gif|jpg|GIF|JPG|rmi|mid|MID|rm|wav|WAV)$ http://www.monsite.tld/hotlinking.gif [R,L]

    Lorsqu’une requête arrive pour un fichier image en provenance d’un autre domaine que monsite.tld, on affiche une image de remplacement.

  • Nicolas Hoffmann Le 19 décembre 2013 à 10:33

    Un autre exemple : rediriger une URL avec querystring vers une autre avec la valeur de la querystring :

    RewriteCond %{QUERY_STRING} id=(\w+)  
    RewriteRule ^ici_l_ancien_chemin/index\.php http://www.nouveau_site.com/nouveau_chemin/index.php?id=%1 [L,R=301]
  • Hervé Renault Le 20 décembre 2013 à 14:04

    Attention, avec Apache 2.4 "Order allow,deny..." c’est fini.
    cf. http://httpd.apache.org/docs/current/upgrading.html#access

  • Dunbar Le 26 avril 2014 à 13:35

    Bonjour,
    Je souhaiterais savoir comment faire ceci :
    j’ai des adresses monsite/article
    et je voudrais que quand il manque l’extension .html il redirige vers monsite/article.html

    D’avance merci

    PS : en n’oubliant pas que certaines adresses sont correct et ne doivent pas être rediriger.

  • Jean Le 8 juillet 2014 à 09:53

    Merci pour cet article récapitulatif.

    Le fichier .htaccess est très puissant, mais il est malheureusement très facile de faire une erreur qui fera planter tout le site !

  • Jarodd Le 4 août 2014 à 21:22

    Bonjour,

    Perso je ne suis pas arrivé à faire ce que je voulais avec mon htaccess : mettre tout le site derrière une identification sauf une seule page (un flux RSS). Si jamais vous avez une idée, je sèche depuis 2 semaines... Merci à vous !
    http://forum.webrankinfo.com/autoriser-une-seule-url-outrepasser-une-identification-htpassd-t174604.html

  • Étien’ Le 19 août 2014 à 10:43

    Merci pour ce post !
    Après avoir essayé plusieurs types de configuration pour la mise en cache, c’est la vôtre qui marche le mieux ! (surtout la commande pour Keep Alive).
    Bref, passé de D à B chez GTmetrix :)

  • Christophe Le 17 janvier 2015 à 18:53

    Comment faire pour que les mots accentués dans la zone d’identification soient correctement accentués ?
    Par exemple : "Accès réservé" s’affiche "Accès réservé"

  • Nicolas Hoffmann Le 18 janvier 2015 à 09:31

    Curieusement, la seule solution que j’ai trouvé est d’encoder le fichier htaccess en ISO-8859-1, et les accents passent. (?)

  • Anne Le 10 février 2015 à 19:40

    Merci pour l’info. Pour ma part je cherche à bloquer dans le htacess les sites d’analyse comme majestic seo ou ahrefs et d’autres , mais je ne sais pas comment faire pouvez-vous m’éclairer ?
    J’ai installé crawlerprotect mais je pense que mon paramétrage est foiré.
    Merci pour vos réponses.

  • Nicolas Hoffmann Le 11 février 2015 à 11:13

    Anne : hormis détecter du user-agent (avec la fiabilité très bancale que cela implique) comme sur http://www.vala-bleu.com/aide/Securite/bloquer-les-spam-bots-et-aspirateurs-de-site-web-avec-.htaccess.html

    ou bloquer des IP, je ne sais pas trop comment faire cela pour être franc (de manière sûre et définitive, ces mesures sont contournables).

  • ramzi Le 25 janvier 2018 à 20:00

    comment je peut faire la redirection sans www vers www avec le fichiers htaccess !!!

  • Nicolas Hoffmann Le 26 janvier 2018 à 10:19

    RewriteCond %HTTP_HOST !^www\. [NC]
    RewriteRule ^ https://www.%HTTP_HOST%REQUEST_URI [R=301,L]

    Avec https ou http selon le besoin.

  • Anonyme Le 15 octobre 2018 à 20:23

    La fonctionnalité permettant de bloquer l’accès aux pages d’un dossier tout en rendant les exécutions possibles ne fonctionne pas. En effet, les dossier css ne n’applique plus, les images ne s’affichent plus et le js non plus.

Vos commentaires

modération a priori

Attention, votre message n’apparaîtra qu’après avoir été relu et approuvé.

Qui êtes-vous ?
Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Suivre les commentaires : RSS 2.0 | Atom