web-dev-qa-db-fra.com

Comment utiliser un RewriteRule et Redirect 301 en même temps?

J'ai mon URL avec plusieurs paramètres:

mydomain.com/?vote.php?ranking=parameter1&lang=parameter2&period=parameter3&provider=parameter4

mais je voudrais changer mes URL en SEO friendly. Mon idée était de relier mes pages à:

mydomain.com/parameter1

..et j'utilise cette RewriteRule dans .htaccess, pour valider la nouvelle adresse:

RewriteCond %{REQUEST_URI}  ^/([^/]+)/?([^/]*)?/?([^/]*)?/?([^/]*)?/?   [NC]
RewriteRule .*    /vote.php?ranking=%2&lang=%1&period=%3&provider=%4  [L,NC]

Mais je ne veux pas changer manuellement tous mes liens, donc j'essaie d'utiliser une règle de redirection en même temps. Est-il possible d'utiliser une redirection 301 sans provoquer de boucle de redirection?

3
Kalimero

Mais je ne veux pas changer manuellement tous mes liens, alors j'essaie d'utiliser une règle de redirection en même temps.

Vous devez modifier manuellement tous vos liens. Ok, il est techniquement possible de le faire sans changer vos liens (voir ci-dessous) - toutefois, cela aura un effet négatif important sur vos utilisateurs et sur le référencement. Si vous ne modifiez pas vos liens dans le code HTML, alors:

  • Vous continuez d'exposer l'ancienne URL aux utilisateurs et aux moteurs de recherche
  • Chaque fois qu'un utilisateur suit un lien sur la page, il sera redirigé en externe. Cela doublera potentiellement le nombre de visites sur votre serveur et inondera vos journaux de réponses 3xx. (Bien qu'une réponse 301 soit, par défaut, mise en cache par le navigateur pendant un certain temps.)
  • De même, les moteurs de recherche vont continuellement explorer les anciennes URL, comme ce sont celles exposées dans votre code HTML.

Réécrire et rediriger simultanément dans .htaccess

Comme indiqué ci-dessus, vous devriez déjà modifier les liens dans votre code HTML.

Cependant, il vous faudra quand même implémenter une redirection comme celle-ci lorsque vous modifiez une structure d'URL existante, car vous devez rediriger les moteurs de recherche ayant déjà indexé le fichier. ancienne structure d'URL afin de préserver le référencement. Vous devez également rediriger les utilisateurs et les autres sites tiers susceptibles d'avoir des signets ou des liens vers les anciennes URL. Si vous n'implémentez pas une telle redirection lorsque change une structure d'URL existante, vous démarrez effectivement le référencement à partir de zéro.

S'il s'agit d'un site tout neuf, cette redirection n'est pas nécessairement requise, car l'ancienne URL ne doit jamais être exposée.

Donc, vous devez rediriger:

example.com/vote.php?ranking=<ranking>&lang=<lang>&period=<period>&provider=<provider>

à:

example.com/<lang>/<ranking>/<period>/<provider>

Notez que les valeurs des paramètres <lang> et <ranking> sont inversées - comme dans votre exemple.

Si tous les paramètres sont obligatoires et toujours dans l'ordre indiqué, vous pouvez procéder comme suit dans .htaccess, avant la réécriture existante:

RewriteCond %{QUERY_STRING} ^ranking=([^&]+)&lang=([^&]+)&period=([^&]+)&provider=([^&]+)
RewriteRule ^vote\.php$ /%2/%1/%3/%4 [QSD,R,L]

Cela supprime complètement la chaîne de requête d'origine de la demande.

Toutefois, si certains ou tous les paramètres d'URL peuvent être omis de la chaîne de requête (ce que votre réécriture semble impliquer) et/ou peuvent être placés dans un ordre différent (par exemple, étiez-vous cohérent dans la façon dont les anciennes URL ont été construites?) alors cela compliquera les choses.

1
MrWhite

J'ai commenté que votre plan suscitait de nombreuses inquiétudes. Pour moi, ça n'a pas l'air génial. Cependant, vous pouvez faire les redirections.

J'adopterais l'approche consistant à ajouter un paramètre redirect=no à votre règle de réécriture:

RewriteRule .*    /vote.php?ranking=%2&lang=%1&period=%3&provider=%4&redirect=no  [L,NC]

Ensuite, dans vote.php, vous pouvez faire la distinction entre les demandes devant être redirigées et les autres.

if (strcmp("no", $_GET['redirect']) !== 0) {
    header("HTTP/1.1 301 Moved Permanently"); 
    header("Location: http://www.example.com/$ranking/$lang/$period/$provider");
}
1