Slash encodé dans L'URL
ma carte est:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with params
new { controller = "Home", action = "Index", id = "" } // Param defaults
);
si j'utilise L'URL http://localhost:5000/Home/About/100%2f200
il n'y a pas de route correspondante.
Je change L'URL en http://localhost:5000/Home/About/100
puis la route est de nouveau appariée.
Est-il un moyen facile de travailler avec des paramètres qui contiennent des barres obliques? D'autres valeurs échappées (espace %20
) semblent fonctionner.
EDIT:
pour coder Base64 fonctionne pour moi. Cela rend l'URL moche, mais C'est OK pour le moment.
public class UrlEncoder
{
public string URLDecode(string decode)
{
if (decode == null) return null;
if (decode.StartsWith("="))
{
return FromBase64(decode.TrimStart('='));
}
else
{
return HttpUtility.UrlDecode( decode) ;
}
}
public string UrlEncode(string encode)
{
if (encode == null) return null;
string encoded = HttpUtility.PathEncode(encode);
if (encoded.Replace("%20", "") == encode.Replace(" ", ""))
{
return encoded;
}
else
{
return "=" + ToBase64(encode);
}
}
public string ToBase64(string encode)
{
Byte[] btByteArray = null;
UTF8Encoding encoding = new UTF8Encoding();
btByteArray = encoding.GetBytes(encode);
string sResult = System.Convert.ToBase64String(btByteArray, 0, btByteArray.Length);
sResult = sResult.Replace("+", "-").Replace("/", "_");
return sResult;
}
public string FromBase64(string decode)
{
decode = decode.Replace("-", "+").Replace("_", "/");
UTF8Encoding encoding = new UTF8Encoding();
return encoding.GetString(Convert.FromBase64String(decode));
}
}
edit 1:
à la fin, il s'est avéré que la meilleure façon était de sauvegarder une corde bien formatée pour chaque élément que je dois sélectionner. C'est bien mieux parce que maintenant je n'encode que les valeurs et ne les décode jamais. Tous les caractères spéciaux deviennent" -". Beaucoup de mes tables db ont maintenant cette colonne supplémentaire "URL". Les données sont assez stables, c'est pourquoi je peux aller par là. Je peux même vérifier, si les données dans "URL" est unique.
EDIT2:
aussi attention au caractère d'espace. Il semble ok sur VS webserver intégré, mais est différent sur iis7 correctement url Encoder caractère d'espace
9 réponses
si ce n'est que votre dernier paramètre, vous pouvez faire:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{*id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }); // Parameter defaults
dans .NET 4.0 beta 2, L'équipe CLR a proposé une solution.
ajoutez ceci à votre site web.fichier de configuration:
<uri>
<schemeSettings>
<add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
</schemeSettings>
</uri>
cela provoque la classe Uri à se comporter selon le RFC décrivant URIs, permettant aux slashes d'être échappés dans le chemin sans être échappés. L'équipe CLR indique qu'ils s'écartent de la spécification pour des raisons de sécurité, et de mettre cela dans votre .le fichier de configuration vous fait prendre la propriété de la sécurité supplémentaire considérations liées au fait de ne pas défaire les entailles.
Voici une explication simple de la solution et un résumé de ce qui a déjà été dit.
Demande côté:
- UrlEncode votre chemin.
- Remplacer le '%' de '!'.
- faire la demande.
réponses:
- remplacer le"!' avec.'%'
- Urldécode votre chemin.
- Utilisez les paramètres comme prévu.
rincer, répéter, apprécier.
Une autre option est d'utiliser une valeur querystring. Très boiteux, mais plus simple que l'encodage personnalisé.
http://localhost:5000/Home/About?100%2f200
idem pour Java / Tomcat.
il y a toujours un problème si vous avez un " / " encodé (%2F) dans votre URL.
RFC 3986 - Section 2.2 dit: "Si les données pour le composant URI serait en conflit avec un caractère réservé du but comme un séparateur, le conflit de données doit être pour cent codé avant l'URI est formé."(RFC 3986 - Section 2.2)
mais il y a un problème avec Tomcat:
http://tomcat.apache.org/security-6.html - fixe dans Apache Tomcat 6.0.10
important: répertoire transversal CVE-2007-0450
Tomcat permet '\', '%2F' et '%5C" [...] .
les propriétés suivantes du système Java ont été ajoutés à Tomcat pour fournir un contrôle supplémentaire de la manipulation de délimiteurs de chemin dans les URLs (les deux options par défaut à false):
- org.Apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH: vrai /faux
- org.Apache.Catalina.connecteur.CoyoteAdapter.ALLOW_BACKSLASH: vrai /faux
en Raison de l'impossibilité de garantir que toutes les URLs sont gérées par Tomcat ils sont dans des serveurs proxy, Tomcat devrait toujours être sécurisé comme si non l'accès au contexte restreint par procuration était utiliser.
affecte: 6.0.0-6.0.9
donc si vous avez une URL avec le caractère %2F, Tomcat retourne: "400 URI invalide: noSlash"
vous pouvez basculer du bugfix dans le script de démarrage Tomcat:
set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
vous pouvez éviter le double encodage/décodage suggestions ci-dessus et tout simplement utiliser HttpServerUtility.UrlTokenEncode et L'UrlTokenDecode correspondante.
c'est intéressant à propos de .NET 4. Quoi qu'il en soit, ce lien décrit la RFC 1738 et inclut les caractères qui doivent être encodés et qui sont tout simplement "dangereux". texte du lien
si je veux une URL conviviale SEO, (comme quand vous voulez mettre un sujet forum post dans L'URL), est de sauter l'encodage et de remplacer tout ce qui n'est pas A-Z, a-z, 0-9.
public static string CreateSubjectSEO(string str)
{
int ci;
char[] arr = str.ToCharArray();
for (int i = 0; i < arr.Length; i++)
{
ci = Convert.ToInt32(arr[i]);
if (!((ci > 47 && ci < 58) || (ci > 64 && ci < 91) || (ci > 96 && ci < 123)))
{
arr[i] = '-';
}
}
return new string(arr);
}
comme suggéré ici quand le problème a été confronté par Symfony 1.x développeurs (+suggéré dans les commentaires PHP pour urlencode()
):
- Coder ' / " à "%2F " avant
urlencode()
- Décoder "%2F' ' / ' après (si nécessaire)
urldecode()
Note: Vous pouvez utiliser rawurlencode()
, mais vous devrez tout de même urlencode '/' deux fois.
avantages:
- évite le recours à d'autres procédés d'échappement (si l'on remplace " / "par un caractère spécial comme"!'ou '_')
- ne dépend d'aucun paramètre de serveur tel que
AllowEncodedSlashes
pour Apache
il suffit d'utiliser Server.UrlDecode
. Il fonctionne, je l'ai testé.