C# URL 中 URL 编码的斜杠
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/591694/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
URL-encoded slash in URL
提问by Mathias F
My Map is:
我的地图是:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with params
new { controller = "Home", action = "Index", id = "" } // Param defaults
);
If I use the URL http://localhost:5000/Home/About/100%2f200
there is no matching route.
I change the URL to http://localhost:5000/Home/About/100
then the route is matched again.
如果我使用 URL http://localhost:5000/Home/About/100%2f200
,则没有匹配的路由。我将 URL 更改为http://localhost:5000/Home/About/100
然后路由再次匹配。
Is there any easy way to work with parameters that contain slashes? Other escaped values (space %20
) seem to work.
有没有简单的方法来处理包含斜杠的参数?其他转义值(空格%20
)似乎有效。
EDIT:
编辑:
To encode Base64 works for me. It makes the URL ugly, but that's OK for now.
对 Base64 进行编码对我有用。它使 URL 变得丑陋,但现在还可以。
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));
}
}
EDIT1:
编辑1:
At the end it turned out that the best way was to save a nicely formated string for each item I need to select. Thats much better because now I only encode values and never decode them. All special characters become "-". A lot of my db-tables now have this additional column "URL". The data is pretty stable, thats why I can go this way. I can even check, if the data in "URL" is unique.
最后发现最好的方法是为我需要选择的每个项目保存一个格式良好的字符串。那好多了,因为现在我只编码值而从不解码它们。所有特殊字符都变成“-”。我的很多数据库表现在都有这个附加列“URL”。数据非常稳定,这就是我可以走这条路的原因。我什至可以检查“URL”中的数据是否唯一。
EDIT2:
编辑2:
Also watch out for space character. It looks ok on VS integrated webserver but is different on iis7 Properly url encode space character
还要注意空格字符。它在 VS 集成网络服务器上看起来不错,但在 iis7 上不同正确 url 编码空格字符
回答by Mehrdad Afshari
If it's only your last parameter, you could do:
如果这只是你的最后一个参数,你可以这样做:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{*id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }); // Parameter defaults
回答by Jon Galloway
One other option is to use a querystring value. Very lame, but simpler than custom encoding.
另一种选择是使用查询字符串值。非常蹩脚,但比自定义编码简单。
http://localhost:5000/Home/About?100%2f200
回答by Andrew Arnott
In .NET 4.0 beta 2, the CLR team has offered a workaround.
在 .NET 4.0 beta 2 中,CLR 团队提供了一种解决方法。
Add this to your web.config file:
将此添加到您的 web.config 文件中:
<uri>
<schemeSettings>
<add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
</schemeSettings>
</uri>
This causes the Uri class to behave according to the RFC describing URIs, allowing for slashes to be escaped in the path without being unescaped. The CLR team reports they deviate from the spec for security reasons, and setting this in your .config file basically makes you take ownership of the additional security considerations involved in not unescaping the slashes.
这会导致 Uri 类根据描述 URI 的 RFC 运行,从而允许在路径中转义斜杠而不进行转义。CLR 团队报告说,出于安全原因,他们偏离了规范,并且在 .config 文件中进行设置基本上可以让您掌握涉及不转义斜杠的其他安全注意事项。
回答by BillB
That's interesting about .NET 4. Anyway, this link describes RFC 1738 and includes which characters need encoding and which are just "unsafe". link text
这对 .NET 4 很有趣。无论如何,这个链接描述了 RFC 1738 并包括哪些字符需要编码,哪些只是“不安全”。 链接文字
If I want an SEO friendly URL, (like when you want to put a forum post subject in the URL), is skip encoding and replace anything that's not A-Z, a-z, 0-9.
如果我想要一个 SEO 友好的 URL(比如当你想在 URL 中放置一个论坛帖子主题时),跳过编码并替换任何不是 AZ、az、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);
}
回答by simonox
Same for Java / Tomcat.
Java / Tomcat 也是如此。
There is still a problem if you have got an encoded "/" (%2F) in your URL.
如果您的 URL 中有一个编码的“/”(%2F),仍然会出现问题。
RFC 3986 - Section 2.2 says: "If data for a URI component would conflict with a reserved character's purpose as a delimiter, then the conflicting data must be percent-encoded before the URI is formed." (RFC 3986 - Section 2.2)
RFC 3986 - 第 2.2 节说:“如果 URI 组件的数据与作为分隔符的保留字符的用途发生冲突,则必须在形成 URI 之前对冲突数据进行百分比编码。” (RFC 3986 - 第 2.2 节)
But there is an Issue with Tomcat:
但是Tomcat存在一个问题:
http://tomcat.apache.org/security-6.html- Fixed in Apache Tomcat 6.0.10
important: Directory traversal CVE-2007-0450
Tomcat permits '\', '%2F' and '%5C' [...] .
The following Java system properties have been added to Tomcat to provide additional control of the handling of path delimiters in URLs (both options default to false):
- org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH: true|false
- org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH: true|false
Due to the impossibility to guarantee that all URLs are handled by Tomcat as they are in proxy servers, Tomcat should always be secured as if no proxy restricting context access was used.
Affects: 6.0.0-6.0.9
http://tomcat.apache.org/security-6.html- 在 Apache Tomcat 6.0.10 中修复
重要:目录遍历 CVE-2007-0450
Tomcat 允许 '\', '%2F' 和 '%5C' [...] 。
以下 Java 系统属性已添加到 Tomcat,以提供对 URL 中路径分隔符处理的额外控制(两个选项默认为 false):
- org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH:真|假
- org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH:真|假
由于无法保证所有 URL 都由 Tomcat 处理,因为它们在代理服务器中,因此 Tomcat 应该始终受到保护,就好像没有使用限制上下文访问的代理一样。
影响:6.0.0-6.0.9
So if you have got an URL with the %2F character, Tomcat returns: "400 Invalid URI: noSlash"
因此,如果您有一个带有 %2F 字符的 URL,Tomcat 将返回:“400 Invalid URI: noSlash”
You can switch of the bugfix in the Tomcat startup script:
您可以在 Tomcat 启动脚本中切换错误修复:
set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
回答by Don Rolling
Here's a simple explanation of the solution and a summation of what has already been said.
这是对解决方案的简单解释以及对已经说过的内容的总结。
Request side:
请求方:
- UrlEncode your path.
- Replace the '%' with '!'.
- Make the request.
- UrlEncode 你的路径。
- 将 '%' 替换为 '!'。
- 提出请求。
Response side:
响应方:
- Replace the '!' with '%'.
- UrlDecode your path.
- Use the parameters as they were intended.
- 更换 '!' 和 '%'。
- UrlDecode 你的路径。
- 按预期使用参数。
Rinse, repeat, enjoy.
冲洗,重复,享受。
回答by Frosty Z
As suggested herewhen the problem was faced by Symfony 1.x developers (+ suggested in PHP comments for urlencode()
):
作为建议在这里当问题面临的Symfony 1.x开发(+建议在PHP征求意见urlencode()
):
- Encode '/' to '%2F' before
urlencode()
- Decode '%2F' to '/' after (if necessary)
urldecode()
- 将 '/' 编码为 '%2F' 之前
urlencode()
- 之后(如有必要)将“%2F”解码为“/”
urldecode()
Note: you can use rawurlencode()
, but you will still have to urlencode '/' twice.
注意:您可以使用rawurlencode()
,但您仍然需要对 '/' 进行两次 urlencode。
Advantages:
好处:
- Avoids the need of additional escaping processes (if replacing '/' with a special character like '!' or '_')
- Do not relies on any server setting such as
AllowEncodedSlashes
for Apache
- 避免需要额外的转义过程(如果将 '/' 替换为特殊字符,如 '!' 或 '_')
- 不要依赖任何服务器设置,例如
AllowEncodedSlashes
Apache
回答by shijas km
Just use Server.UrlDecode
. It will work, I've tested.
只需使用Server.UrlDecode
. 它会起作用,我已经测试过了。
回答by silentnoise
You can avoid the double encoding/decoding suggestions above and simply use HttpServerUtility.UrlTokenEncode and the corresponding UrlTokenDecode.
您可以避免上述双重编码/解码建议,只需使用 HttpServerUtility.UrlTokenEncode 和相应的 UrlTokenDecode。
回答by user11406534
For inbound encoded '/' issue, I was able to fix my issue by adding '*' to catchall the id parameter and then was able to passing an encoded '/' into the the control correctly (the parameter was a string with an encoded '/')
对于入站编码的“/”问题,我能够通过添加“*”来解决我的问题,以捕获所有 id 参数,然后能够将编码的“/”正确传递到控件中(参数是带有编码的字符串) '/')
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{*id}",
defaults: new
{
controller = "Control",
action = "Action",
id = UrlParameter.Optional
})