web-dev-qa-db-fra.com

RewriteRule ne fonctionne pas pour un fichier CSS et un document lorsqu'un RewriteCondition est ajouté pour tester si un paramètre de valeur de nom est dans la chaîne de requête

J'essaye de changer le DocumentRoot en subfolder via .htaccess.

Cela fonctionne bien ...

RewriteCond %{REQUEST_URI} !subfolder/
RewriteRule ^(.*)$ /subfolder/$1

... cependant, je ne veux le faire que lorsqu'un paramètre de requête spécifique (var=test) est défini, donc j'ai ceci:

RewriteCond %{QUERY_STRING} ^var=test$
RewriteCond %{REQUEST_URI} !subfolder/
RewriteRule ^(.*)$ /subfolder/$1

... mais pour une raison quelconque, cela ne fonctionne pas.

Des suggestions sur ce que le problème pourrait être?


PDATE: Voici un exemple complet (simplifié):

.htaccess

RewriteEngine on
RewriteCond %{QUERY_STRING} (.*(?:^|&))var=test((?:&|$).*)
RewriteCond %{REQUEST_URI} !sites/test/
RewriteRule ^(.*)$ /sites/test/$1

sites/test/index.php

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
    <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
    <p>Test</p>
</body>
</html>

sites/test/styles.css

* {
    color: red;
}

Essayez maintenant de charger la page avec http://example.com/?var=test. Le texte Test devrait être en rouge, mais ce n'est pas le cas.

Supprimez la ligne QUERY_STRING RewriteCond, et cela fonctionne.

Mais je dois être capable de vérifier la chaîne de requête en quelque sorte ..

hôte virtuel Apache (au besoin)

<VirtualHost *:80>

      ServerName www.example.com
      ServerAdmin [email protected]

      DocumentRoot "/var/www/mainsite"
      <Directory />
              Options FollowSymLinks
              AllowOverride None
      </Directory>
      <Directory "/var/www/mainsite">
              Options Indexes FollowSymLinks MultiViews
              AllowOverride All
              Order allow,deny
              allow from all
      </Directory>

</VirtualHost>
4
camursm

Pour une raison quelconque, le deuxième bloc de code ci-dessus divise les chemins de fichiers CSS, et je ne comprends pas pourquoi ...

La seule différence avec le second bloc de code est que la demande de votre/vos fichier (s) CSS ne sera pas réécrite. Alors que ce sera pour le premier bloc de code. Votre URL CSS ne contient pas le paramètre URL var=test. Seule l'URL de la page principale est en cours de réécriture, elle contient le paramètre URL.

Donc, étant donné une demande de http://example.com/?var=test, alors /styles.css sera demandé (et non pas réécrit), au lieu de /sites/test/styles.css, ce qui semble être l'intention.


PDATE # 1: Comme mentionné dans les commentaires, il ne serait probablement pas pratique d'essayer de résoudre ce problème avec .htaccess. La demande du fichier CSS est une demande entièrement distincte. Il n'y a pas de concept de "session" ici (ou plutôt de "demande de page"). Vous devez avoir recours aux cookies pour conserver l'état, ce qui ajoute à la complexité (il faudra le désactiver pour d'autres demandes) et risque de ne pas être fiable. Si vous voulez rester avec la chaîne de requête trigger , vous pouvez résoudre ce problème dans PHP en vérifiant le var=test chaîne de requête et l'ajoutant manuellement à l'URL CSS dans votre code HTML. (Ou même d'ajouter le chemin URL complet (complet) à l'URL CSS dans votre code HTML, même si vous essayez peut-être de cacher le véritable chemin de l'URL à vos utilisateurs, pour que cela ne soit pas souhaitable.)

Par exemple:

<?php
$resourceQueryString = '';
if (isset($_GET['var']) && ($_GET['var'] == 'test')) {
    $resourceQueryString = '?var=test';
}
?>
<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
    <link rel="stylesheet" type="text/css" href="styles.css<?=$resourceQueryString?>">
</head>
<body>
    <p>Test</p>
</body>
</html>

Cela vérifie naturellement var=test n'importe où dans la chaîne de requête, et non littéralement ?var=test.

Cependant, si vous avez des centaines de pages statiques, cela risque de ne pas être pratique non plus.


PDATE # 2: Si vous vouliez essayer l'approche "cookie" dans .htaccess, vous pourriez peut-être faire quelque chose comme ceci (non testé):

RewriteEngine on

# If query string passed then set a (session) cookie...
RewriteCond %{QUERY_STRING} (?:^|&)var=test(?:&|$)
RewriteRule ^ - [CO=rewrite_trigger:1:.example.com]

# If no query string and a ".php" request then unset cookie
RewriteCond %{QUERY_STRING} !var=test
RewriteRule \.php$ - [CO=rewrite_trigger:0:.example.com:-1]

# Rewrite request if query string OR cookie is set
RewriteCond %{QUERY_STRING} (?:^|&)var=test(?:&|$) [OR]
RewriteCond %{HTTP_COOKIE} rewrite_trigger=1
RewriteCond %{REQUEST_URI} !^/sites/test/
RewriteRule (.*) /sites/test/$1 [L]

Changez .example.com pour correspondre à votre domaine.

Gardez à l'esprit que le cookie n'est pas lisible sur la demande pour laquelle le cookie est réellement défini. Le cookie ne peut être lu que lors de demandes ultérieures, d'où la nécessité de rechercher la chaîne de requête OR le cookie.

Notez que ceci n’a pas encore été testé (pourra le tester plus tard si j’en ai le temps). En fait, en y réfléchissant, il pourrait y avoir un problème avec la première demande .php sans la chaîne de requête après un .php request avec la chaîne de requête (car le cookie sera toujours défini). Peut-être besoin d'une variable d'environnement pour résoudre ce problème? Ou peut-être vérifier (chaîne de requête ET .php) OR (cookie ET non .php) afin de réécrire?

4
MrWhite