如何编码包含哈希的路径?

Posted

技术标签:

【中文标题】如何编码包含哈希的路径?【英文标题】:How to encode a path that contains a hash? 【发布时间】:2012-03-08 08:17:33 【问题描述】:

如何正确编码包含 哈希 (#)路径?请注意,哈希不是片段(书签?)指示符,而是路径名的一部分。

例如,如果有这样的路径:

http://www.contoso.com/code/c#/somecode.cs

当你尝试这样做时会导致问题:

Uri myUri = new Uri("http://www.contoso.com/code/c#/somecode.cs");

它似乎将散列解释为片段指示符。

手动把#换成%23感觉不对。是否还有其他需要替换的字符? 在 Uri 和 HttpUtility 中有一些转义方法,但似乎没有一个可以解决问题。

【问题讨论】:

【参考方案1】:

有几个字符是你不应该使用的。可以试试work your way through this very dry documentation,或者参考这个handy URL summary on Stack Overflow。

如果您查看这个网站,您会看到他们的 C# 问题编码为 %23

Stack Overflow C# Questions

您可以使用任一方法(对于 ASP.NET):

string.Format("http://www.contoso.com/code/0/somecode.cs", 
    Server.UrlEncode("c#")
);

或者对于类库/桌面:

string.Format("http://www.contoso.com/code/0/somecode.cs",
    HttpUtility.UrlEncode("c#")
);

【讨论】:

请注意,以这种方式编码整个 URL(包括方案和路径)实际上会产生一个不是有效 URI 的字符串。它抛出 Invalid URI: 如果您尝试从中构造 URI,则无法确定 URI 的格式。 我认为这里忽略了重点。这不仅仅是关于# 字符的只是,而是如何构造一个具有可能包含任何无效字符的有效路径的任意URI。 @Dodgyrabbit 鉴于我们不知道 URL 的哪些部分是动态的,我将其留给 OP 来决定在哪里使用实用程序类。 我不认为 System.Web.HttpUtility.UrlEncode 摆脱了 # 符号,我只是尝试过它仍然存在,这会截断服务器端的查询。 @Ted 结果是 C%23 - 你是如何测试这个值的?【参考方案2】:

又找了一些挖坑的朋友,发现Java的一个重复问题: HTTP URL Address Encoding in Java

但是,.Net Uri 类不提供我们需要的构造函数,但 UriBuilder 可以。

因此,为了在路径包含非法字符的情况下构造正确的 URI,请执行以下操作:

// Build Uri by explicitly specifying the constituent parts. This way, the hash is not confused with fragment identifier
UriBuilder uriBuilder = new UriBuilder("http", "www.contoso.com", 80, "/code/c#/somecode.cs");

Debug.WriteLine(uriBuilder.Uri);
// This outputs: http://www.contoso.com/code/c%23/somecode.cs

注意它如何不必要地转义不需要转义的 URI 部分(如 :// 部分),这是 HttpUtility.UrlEncode 的情况。看起来这个类的目的实际上是对 URL 的查询字符串/片段部分进行编码 - 而不是方案或主机名。

【讨论】:

【参考方案3】:

使用UrlEncode:System.Web.HttpUtility.UrlEncode(string)

class Program

    static void Main(string[] args)
    
        string url = "http://www.contoso.com/code/c#/somecode.cs";
        string enc = HttpUtility.UrlEncode(url);

        Console.WriteLine("Original: 0 ... Encoded 1", url, enc);
        Console.ReadLine();
    

【讨论】:

示例中的字符串 enc 尽管已转义,但不再是有效的 URI。试试 Uri uri = new Uri(enc) 你会看到它抛出 Invalid URI 异常。不过找到了正确的解决方案。 有趣。然后,我对 MSDN 文档有点困惑,它说 Encodes a URL string。 UrlEncode 方法可用于对整个 URL 进行编码,包括查询字符串值。(请参阅msdn.microsoft.com/en-us/library/…)

以上是关于如何编码包含哈希的路径?的主要内容,如果未能解决你的问题,请参考以下文章

Jersey - servlet 上下文路径和/或 servlet 路径包含百分比编码的字符

如何在 URL 中转义哈希字符

redis_哈希对象

如何找到包含匹配值的哈希键

Plotly 注释文本:在 URL 中编码哈希 (#) 字符

解决URL路径包含+等特殊符号,编码也无效的办法