web-dev-qa-db-fra.com

htaccess nécessite une redirection automatique + une langue + des URL de référencement

J'essaie de réaliser plus de choses:

  1. HTTP: // devrait rediriger vers HTTPS: //
  2. www.example.com doit rediriger vers www.example.com/en/ ou/it/en fonction de la langue du client
  3. les liens doivent être résolus en www.example.com?lang=fr
  4. Toutes les URL différentes de index.php? (par exemple, www.example.com/abcd) doivent tous être redirigés vers index.php

Je travaille avec la 1.3.4 en utilisant:

RewriteEngine On

RewriteCond %{SERVER_PORT} !^443$ 
RewriteCond %{HTTPS} off 
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

# RewriteCond %{HTTP:Accept-Language} ^en [NC]
# RewriteRule ^$ https://www.example.com/en/ [L,R=301]
# RewriteCond %{HTTP:Accept-Language} ^it [NC]
# RewriteRule ^$ https://www.example.com/it/ [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(en|it)/(.*) $2?lang=$1 [QSA]
RewriteRule ^([^/]+)$ index.php?op=$1 [L,NS,QSA] index.php

Essayer maintenant d’atteindre le point 2. Si je supprime les commentaires, cela aboutit à une boucle de redirection + erreur

Y a-t-il un moyen?

2
Mario Bruscella

Cette réponse vient de mémoire. Si ma syntaxe est correcte à 100%, vous voudrez remplacer vos 4 lignes de code commentées par:

RewriteCond %{REQUEST_URI} !^/en(.*)$
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteRule ^$ https://www.example.com/en/ [L,R=301]
RewriteCond %{REQUEST_URI} !^/it(.*)$
RewriteCond %{HTTP:Accept-Language} ^it [NC]
RewriteRule ^$ https://www.example.com/it/ [L,R=301]

L’intention ici est de vérifier l’URI de la demande (la partie qui vient après https://www.example.com ) et de s’assurer que c’est tout sauf l’URI que vous souhaitez rediriger (évitant ainsi une rediriger la boucle). Si l'URI de la demande correspond, la règle n'est pas traitée.

Par exemple:

RewriteCond %{REQUEST_URI} !^/en(.*)$

..checks pour voir que quelqu'un n'a pas tapé une URL qui commence par https://www.example.com/en et si c'est le cas, c'est coché:

RewriteCond %{HTTP:Accept-Language} ^en [NC]

..which vérifie que "en" est dans l'en-tête accept-language. Si l'en-tête a "en" et que l'URL ne commence pas par https://www.example.com/en , l'utilisateur qui tente d'accéder à https: // www. example.com/ sera redirigé vers https://www.example.com/en/ via cette règle:

RewriteRule ^$ https://www.example.com/en/ [L,R=301]
1
Mike

La boucle de réécriture est en fait causée par des règles plus loin dans votre script:

_RewriteRule ^(en|it)/(.*) $2?lang=$1 [QSA]
RewriteRule ^([^/]+)$ index.php?op=$1 [L,NS,QSA] index.php
_

Après avoir redirigé l'utilisateur vers _/en/_ (avec les règles _Accept-Language_), la première directive réécrit ici la demande en _?lang=en_ (aucun chemin d'URL) mais la deuxième directive ne correspond pas ( puisqu'il n'y a pas de chemin d'URL), il n'est donc pas réécrit en _index.php_ (un chemin d'URL). Le processus de réécriture d'URL recommence alors et l'utilisateur est redirigé vers _/en/_ (car il n'y a pas de chemin d'URL), etc.

Si votre script peut gérer un paramètre op vide (il devrait l'être), vous pourrez probablement le résoudre en modifiant simplement le dernier motif RewriteRule de ^([^/]+)$ à ^([^/]*)$ pour attraper la chaîne vide.

OU, assurez-vous que votre avant-dernière RewriteRule inclut toujours un chemin URL. Par exemple, changez:

_RewriteRule ^(en|it)/(.*) $2?lang=$1 [QSA]
_

à

_RewriteRule ^(en|it)/(.*) index.php?op=$2&lang=$1 [QSA,L]
_

Bien que cela duplique vraiment ce que fait la dernière directive (d'où l'ajout du drapeau L.).

OU, incluez une condition dans votre redirection de langue et redirigez uniquement lorsque le paramètre lang URL n'est pas présent. Par exemple:

_RewriteCond %{QUERY_STRING} !lang=[a-z]{2}
RewriteCond %{HTTP:Accept-Language} ^(en|it) [NC]
RewriteRule ^$ https://www.example.com/%1/ [L,R=301]
_

Cela combine également les deux règles (en et it) en une.

Juste pour ajouter ... Bien que ce type de détection de langue soit courant, il est peut-être trop simplifié et pourrait entraîner une détection de langue incorrecte. Il suppose que les langues sont spécifiées afin de choisir une préférence (ce qu'elles pourraient ne pas être)) et ignore le paramètre "quality" (q). (Il y a eu d'autres questions sur ce sujet même, mais je ne peux pas les trouver pour le moment.)


De plus, avez-vous besoin de vérifier les deux ...?

_RewriteCond %{SERVER_PORT} !^443$ 
RewriteCond %{HTTPS} off
_
1
MrWhite