====== Diriger une ressource inexistante ====== Plutôt que d'utiliser la réécriture pour faire ceci : RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule .* /handler.php [L] Depuis la version 2.2.16, il est possible d'utiliser [[http://httpd.apache.org/docs/2.2/mod/mod_dir.html#fallbackresource|FallbackResource]] : FallbackResource /handler.php (ErrorDocument 404 /handler.php n'étant pas une solution, c'est le dernier maillon de la chaîne : réécriture > FallbackResource > ErrorDocument) ====== Les caractères "spéciaux" ====== Windows (et Mac ?) est un cas à part : il dispose d'une API Unicode (UTF-16) dédiée dont Apache (APR en réalité) tire partie. Par conséquent, l'URL **doit** être encodée en UTF-8 (APR réalise les conversions UTF-8 <=> UTF-16). Cependant, la réécriture ne semble pas fonctionner avec de l'UTF-8 : * un .htaccess en UTF-8 (sans BOM sinon erreur 500 assurée) * un .htaccess ASCII/ANSI (ie en écrivant les unités de code à la main : exemple ä écrit en ä) * urlencodant les URLs (ä écrit en %C3%A4) La solution qui semble marcher est l'écriture hexadécimale des unités de code (\xC3\xA4) Note : par contre, il ne faut pas utiliser une classe (exemple : [aàäá]) mais des alternatives ((?:a|\xC3\xA0|\xC3\xA4|\xC3\xA1) pour le même exemple) puisque le caractère peut demander plusieurs octets/unités de code. (Windows uniquement) L'erreur 403 consignée comme "(22)Invalid argument: Cannot map ..." dans le journal d'erreur (pas d'accès) signifierait que ce n'est pas de l'UTF-8 (valide) (la requête est probablement en ISO). Et l'erreur 404, signifierait qu'il n'y a pas réécriture. Par conséquent, ne pas omettre de faire envoyer la requête en UTF-8 par le navigateur. C'est généralement le cas par défaut à présent et est normalement configurable. Sous Firefox, quand la requête n'est pas en UTF-8, les caractères spéciaux sont urlencodées. Attention : que le lien de la page soit encodé en UTF-8 ou en ISO, le navigateur la renverra selon sa configuration. Du moins c'est le cas sous Firefox, quand network.standard-url.encode-utf8 est à TRUE (valeur par défaut, voir about:config), où l'adresse du lien en ISO est renvoyée/suivie en UTF-8 (réencodage interne au client). En revanche, sous Firefox, un lien urlencodé, est repris tel quel (donc l'encodage initial est conservé). Unixoïde (Mac exclus ?) : rien de particulier, il ne traite que des octets. Le tout est donc de respecter l'encodage initial du nom. Les fichiers physiques en eux-même : * Windows (et Mac ?) : le nom doit être en UTF-8 (pour LA raison évoquée ci-dessus, excepté si APR venait à être compilé sans APR_HAS_UNICODE_FS) * Unixoïde (Mac exclus ?) : respecter l'encodage initial du nom Pour récapituler : * Windows : impose/requiert l'usage d'UTF-8 * Unixoïde : il faut respecter l'encodage du fichier ou de la réécriture * Pour faire de la réécriture sur caractères spéciaux en UTF-8 : coder les unités de code en hexadécimal (\xDD) Comportement d'autres clients majeurs : * Chrome : même comportement que Firefox ; recode les URL non-urlencodée en UTF-8 (URL urlencodée = encodage conservé) * IE (8) : idem * Opera : idem Par conséquent, UTF-8 serait l'encodage le plus portable, bien que particulièrement inadéquat à gérer en réécriture. Quoi qu'il en soit, toujours urlencodé (fonction PHP urlencode) ses liens ; c'est le meilleur moyen de lever toute ambiguïté. ====== Duplicate content ====== Dans le cas où une même ressource pourrait avoir plusieurs adresses (ce qui arrive généralement avec la réécriture) pour être certain de ne pas être ensuite pénalisé pour duplicate content, ajouter une balise link rel="canonical" indiquant l'URL "officielle" : ====== Variables d'environnement : qui utilise quoi ? ====== Les variables d'environnement sont en réalité gérées par 2 tables différentes au niveau d'Apache : * la table (apr_table_t) //subprocess_env// (membre de la structure request_rec) * la table (apr_table_t) //notes// (membre de la structure request_rec) struct request_rec { // ... /** Array of environment variables to be used for sub processes */ apr_table_t *subprocess_env; /** Notes from one module to another */ apr_table_t *notes; // ... }; * SetEnvIf : consulte uniquement //subprocess_env// (et celle créée l'est dans cette dernière) * réécriture (''%%%{ENV:X}%%'') : consulte les deux, d'abord //notes// puis //subprocess_env// * les expressions (Apache >= 2.4), fonction ''%%env('X')%%'' ou variable ''%%%{env:X}%%'' : consulte d'abord //notes// puis //subprocess_env// puis le système (getenv) - la première trouvée parmi ces 3 emplacements l'emporte * Deny (Apache < 2.4) et Require env (Apache >= 2.4) : consulte uniquement //subprocess_env//