urlencoded barre oblique est la rupture URL
à propos du système
j'ai des URLs de ce format dans mon projet: -
http://project_name/browse_by_exam/type/tutor_search/keyword/class/new_search/1/search_exam/0/search_subject/0
où" paire de mots clés/classe "signifie recherche avec "classe" mot clé.
j'ai un index commun.fichier php qui exécute pour chaque module du projet. Il n'existe qu'une règle de réécriture pour supprimer l'index.php de L'URL: -
RewriteCond !^(index.php|resources|robots.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
j'utilise urlencode () lors de la préparation de L'URL de recherche et urldecode () lors de la lecture de L'URL de recherche.
problème
seul le caractère slash forward casse les URLs provoquant 404 page non trouvée erreur.
Par exemple, si je cherche one/two
L'URL est
http://project_name/browse_by_exam/type/tutor_search/keyword/one%2Ftwo/new_search/1/search_exam/0/search_subject/0/page_sort/
comment arranger ça? J'ai besoin de conserver l'index.php caché dans L'URL. Sinon, si ce n'était pas nécessaire, il n'y aurait eu aucun problème avec forward slash et j'aurais pu utiliser cette URL:-
http://project_name/index.php?browse_by_exam/type/tutor_search/keyword/one
%2Ftwo/new_search/1/search_exam/0/search_subject/0
12 réponses
Apache nie toutes les URLs avec %2F
dans la partie chemin, pour des raisons de sécurité: les scripts ne peuvent pas normalement (par ex. sans réécriture) faire la différence entre %2F
et /
en raison de la variable d'environnement PATH_INFO
étant automatiquement URL-décodé (ce qui est stupide, mais une partie de longue date de la spécification CGI donc il n'y a rien à faire à ce sujet).
vous pouvez désactiver cette fonctionnalité en utilisant le AllowEncodedSlashes
La directive , mais notez que d'autres serveurs Web vont encore la désactiver (sans possibilité de l'éteindre), et que d'autres caractères peuvent aussi être tabous (par ex. %5C
), et que %00
en particulier sera toujours bloqué à la fois par Apache et IIS. Ainsi, si votre application se fiait à la possibilité d'avoir %2F
ou d'autres caractères dans une partie de chemin, vous limiteriez vos options de compatibilité/déploiement.
j'utilise urlencode () alors que préparation de L'URL de recherche
vous devez utiliser rawurlencode()
, pas urlencode()
pour échapper à des pièces de chemin. urlencode()
est mal nommé, il est en fait pour application/x-www-form-urlencoded
données telles que dans la chaîne de requête ou le corps d'une requête POST, et pas pour d'autres parties de l'URL.
la différence est que +
ne signifie pas l'espace dans les parties de chemin. rawurlencode()
produira correctement %20
à la place, qui fonctionne à la fois dans les données form-encoded et d'autres parties de L'URL.
dans Apache, AllowEncodedSlashes On empêcherait le rejet immédiat de la requête avec un 404.
encore une idée pour arranger ça.
remplacer %2F par %252F après l'encodage de l'url
PHP
function custom_http_build_query($query=array()){
return str_replace('%2F','%252F', http_build_query($query));
}
gérer la requête via htaccess
.htaccess
RewriteCond %{REQUEST_URI} ^(.*?)(%252F)(.*?)$ [NC]
RewriteRule . %1/%3 [R=301,L,NE]
ressources
j'ai eu le même problème avec slash dans url get param, dans mon cas suivant le code php fonctionne:
$value = "hello/world"
$value = str_replace('/', '/', $value;?>
$value = urlencode($value);?>
# $value is now hello%26%2347%3Bworld
je remplace d'abord la barre oblique par l'entité html, puis je fais l'encodage de l'url.
sur mon compte d'hébergement ce problème a été causé par une règle de sécurité mods qui a été définie automatiquement pour tous les comptes. Lorsque j'ai signalé ce problème, leur administrateur a rapidement supprimé cette règle pour mon compte.
utiliser un caractère différent et remplacer le côté serveur slashes
p.ex. Drupal.org utilise %21 (le caractère de la marque d'excalamation ! pour représenter la barre oblique dans un paramètre de l'url.
les deux liens ci-dessous fonctionnent:
https://api.drupal.org/api/drupal/includes%21common.inc/7
https://api.drupal.org/api/drupal/includes-oui.commun.inc / 7
si vous craignez que le personnage puisse entrer en conflit avec un personnage du paramètre, utilisez une combinaison de caractères.
pour que votre url soit http://project_name/browse_by_exam/type/tutor_search/keyword/one_-!two / new_search/1/search_exam/0/search_subject/0
changement avec js et le reconvertir en un slash côté serveur.
une solution standard pour ce problème est d'autoriser les slashes en faisant du paramètre qui peut contenir des slashes le dernier paramètre de l'url.
pour une url de code produit que vous auriez alors...
mysite.com/product/details/PR12345/22
pour un terme de recherche vous auriez
http://project/search_exam/0/search_subject/0/keyword/Psychology/Management
(le mot clé ici est Psychologie/gestion)
ce n'est pas beaucoup de travail de traiter les premiers paramètres "nommés" puis concatter le les autres sont des codes produits ou des mots-clés.
certains cadres ont cette facilité intégrée à leurs définitions de routage.
ceci ne s'applique pas à l'utilisation de cas impliquant deux paramètres que mon contiennent des barres obliques.
est simple pour moi de l'utiliser base64_encode
$term = base64_encode($term)
$url = $youurl.'?term='.$term
après avoir décodé le terme
$term = base64_decode($['GET']['term'])
de cette façon encodent le "/" et " \
j'utilise la fonction javascript encodeURI() pour la partie URL qui a des slashs qui devraient être vus comme des caractères au lieu de l'adresse http. Par exemple:
"/api/activites/" + encodeURI("?categorie=assemblage&nom=Manipulation/Finition")
j'ai résolu cela en utilisant 2 fonctions personnalisées comme so:
function slash_replace($query){
return str_replace('/','_', $query);
}
function slash_unreplace($query){
return str_replace('_','/', $query);
}
pour coder je pourrais appeler:
rawurlencode(slash_replace($param))
et pour décoder je pourrais appeler
slash_unreplace(rawurldecode($param);
santé!
vous pouvez utiliser %2F
si vous l'utilisez de cette façon:
?param1=value1¶m2=value%2Fvalue
mais si vous utilisez /param1=value1/param2=value%2Fvalue
il lèvera une erreur.