代码之家  ›  专栏  ›  技术社区  ›  Kelly Robins

ASP.NET URL编码

  •  6
  • Kelly Robins  · 技术社区  · 17 年前

    我正在ASP.NET中实现URL重写,我的URL给我带来了一个问题世界。

    URL是从部门和类别的数据库生成的。我希望员工能够在不破坏网站的情况下,使用任何特殊字符向数据库添加项目。

    在构造URL之前,我正在对数据进行编码。

    有几个问题…

    1. IIS在URL到达.NET之前对其进行解码,使其无法正确解析包含“/”的任何内容。
    2. ASP.NET会被在某些页面中使“~”无效的URL混淆。
    3. 我从内置测试服务器迁移到本地IIS服务器(XP计算机),任何包含编码的&(%26)的URL都会给我一个“错误请求”错误。
    4. urlencode会保留一些中断字符,如“.”

    我在这个问题上确实有另外两个相关的帖子,当时我只看到小问题而不是上游的大问题。我发现了一些注册表技巧来解决“坏请求”问题,但我将部署到一个共享的托管环境中,使其变得毫无用处。我还知道这是对某些安全问题的修复,所以我不想在不知道我打开的蠕虫能做什么的情况下绕过它。

    与其强迫.NET将原始URL传递给我,或者重写IIS设置,我首先要做的是真正安全的URL。

    我会注意到我已经尝试过antixss.urlencode、httputility.urlencode、uri.escapedatastring。我甚至尝试过一些愚蠢的事情,比如双重犯罪。有没有一个实用程序可以满足我的需要,或者我真的需要自己滚动。我甚至在考虑做一些不寻常的事情,比如用一个不寻常的字符串来替换百分比。最终的结果至少应该是可读的,即首先使用URL重写的点。

    抱歉,这篇长文章-我只是想确保我已经包含了所有必要的细节。我似乎找不到任何有关这方面的信息,而且这似乎是一个常见的问题-所以也许我遗漏了一些大问题。谢谢你的帮助,耐心的解释!


    为清晰起见编辑:

    当我说URL是从数据库构建的,我的意思是目录结构是从我的数据库中的部门和类别构建的。

    一些示例URL-

    mystore/冰箱/酒吧+冰箱.aspx
    mystore/烹饪+设备.aspx
    mystore/厨房/切割+木板.asxpx

    当我使用诸如“饮料和酒吧”或“糕点/装饰”这样的部门来构建我的URL时,问题就出现了。尽管首先被编码,但这些都会导致上述问题。

    除了特殊的字符编码问题外,我的处理程序已经实现并且工作正常。

    4 回复  |  直到 10 年前
        1
  •  5
  •   eulerfx    17 年前

    您应该考虑在您的类别/部门表之外创建一个表,其中每个类别都有一个唯一的URL。然后您可以使用一个特殊的例程来生成URL。这可以是一个SQL标量函数,也可以是一个clr函数,但是它要做的一件事是规范化Web的URL。您可以将“饮料&酒吧”转换为“饮料和酒吧”,将“糕点/装饰”转换为“糕点装饰”。通常,例程需要用其他东西替换所有无效的HTTP URL字符。例如:

    public static class URL
    {
        static readonly Regex feet = new Regex(@"([0-9]\s?)'([^'])", RegexOptions.Compiled);
        static readonly Regex inch1 = new Regex(@"([0-9]\s?)''", RegexOptions.Compiled);
        static readonly Regex inch2 = new Regex(@"([0-9]\s?)""", RegexOptions.Compiled);
        static readonly Regex num = new Regex(@"#([0-9]+)", RegexOptions.Compiled);
        static readonly Regex dollar = new Regex(@"[$]([0-9]+)", RegexOptions.Compiled);
        static readonly Regex percent = new Regex(@"([0-9]+)%", RegexOptions.Compiled);
        static readonly Regex sep = new Regex(@"[\s_/\\+:.]", RegexOptions.Compiled);
        static readonly Regex empty = new Regex(@"[^-A-Za-z0-9]", RegexOptions.Compiled);
        static readonly Regex extra = new Regex(@"[-]+", RegexOptions.Compiled);
    
        public static string PrepareURL(string str)
        {
            str = str.Trim().ToLower();
            str = str.Replace("&", "and");
    
            str = feet.Replace(str, "$1-ft-");
            str = inch1.Replace(str, "$1-in-");
            str = inch2.Replace(str, "$1-in-");
            str = num.Replace(str, "num-$1");
    
            str = dollar.Replace(str, "$1-dollar-");
            str = percent.Replace(str, "$1-percent-");
    
            str = sep.Replace(str, "-");
    
            str = empty.Replace(str, string.Empty);
            str = extra.Replace(str, "-");
    
            str = str.Trim('-');
            return str;
        }
    }
    

    您可以将其设置为SQL增强函数,或者将URL生成作为单独的进程运行。然后,为了实现映射,您可以将整个URL直接映射到一个类别ID。从长远来看,这种方法更好,原因有几个。首先,您并不总是生成URL,您只需执行一次,它们就会保持静态,您不必担心过程更改,然后GoogleBot就无法找到旧的URL。此外,如果发生冲突,您可能会注意到一个可能重复的类别名称,因为冲突只会因特殊字符而不同。最后,您可以从数据库中查看URL,而不必运行映射函数。

        2
  •  2
  •   Daisy Moon    17 年前

    我在begin-authenticated请求的global.asax文件中实现了一个URL重写,因为我有一些安全性。这是我获取原始URL然后进行数据库查找的地方。然后,这将重写到ASPX页的路径,所有参数都将通过查询字符串传递。不需要编码。

    但是,如果您使用URL实际更改数据,那么我可以看到您将遇到巨大的问题,因为您正在有效地使用HTTPGET更改数据库。它通常是一个坏主意,而不是我做的事情。

    我只使用post请求进行任何数据库操作。这将保持URL的清洁,因为所有数据都在页面表单中。

    我唯一要做的就是为page.form.action设置正确的URL,在大多数情况下,这是原始URL。

    如果它是导致问题的类别名称,那么您可能应该将名称仅限于字母数字字符,并将空格替换为“-”。在查找文件名时,IIS将抛出一个带有句点“.”的不稳定字符串。

    附笔。 IIS不理解波浪线“~”,这是编译器可以理解的。因此,如果在锚标记中使用它,它将无法按预期工作,您应该使用应用程序根目录而不是tilde。

    编辑:

    好的,这看起来像是IIS在某些字符上有问题,例如。和/和。即使您执行了URLENCODE,这些IIS仍将尝试实现其自身的含义。 因此,考虑移除它们,以便:

    饮料和酒吧成为Beveragebar

    糕点/装饰成为糕点装饰。

    这将使您的URL保持干净,但这确实意味着数据库中有一个额外的列,因此您可以根据这个缩短的类别名称来检查URL。

        3
  •  1
  •   marc_s MisterSmith    10 年前

    我也有同样的问题。谢谢你写得这么好。它实际上帮助我更好地理解这个问题。

    不过,我还有其他的考虑。我的目标之一是支持URL中基于文章标题的任何字符的潜力。另外,我想确保编码和双向编码/解码过程的唯一性。

    所以我做了一些手工编码来解决这个问题。这不会完全消除百分比编码,但会大大减少编码,并防止用户生成不可访问的URL。我的过程从使用 Server.URLEncode 功能。但这并不能消除URL中的问题。因为IIS正在解码该URL,然后将其传递给应用程序,所以某些字符会破坏该URL,并引发危险的请求异常。这些字符包括 +, &, /, !, *, ., ( ) . 因此,对于那些字符加上其他字符,我想让它们更具可读性,我对一个更有用的URL进行了双重编码。由于URL中允许的字符数有限,编码也很困难。所以在编码之前,我把所有字母都大写,然后用小写字母进行编码。这可以防止它完全可解码,但是我可以通过使我希望匹配的值为大写来轻松地在数据库或代码中进行匹配。

    好吧,这是我的密码。我们将感谢您的反馈。哦,是的,这是在vb中,但事情应该转移到c足够简单。

    Dim strReturn As String = Trim(strStringToEncode)
    strReturn = Server.UrlEncode(strReturn)
    
    strReturn = strReturn.Replace("-", "dash").Replace("+", "-")
    
    strReturn = strReturn.Replace("%26", "and").
                        Replace("%2f", "or").
                        Replace("!", "excl").
                        Replace("*", "star").
                        Replace("%27", "apos").
                        Replace("(", "lprn").
                        Replace(")", "rprn").
                        Replace("%3b", "semi").
                        Replace("%3a", "coln").
                        Replace("%40", "at").
                        Replace("%3d", "eq").
                        Replace("%2b", "plus").
                        Replace("%24", "dols").
                        Replace("%25", "pct").
                        Replace("%2c", "coma").
                        Replace("%3f", "query").
                        Replace("%23", "hash").
                        Replace("%5b", "lbrk").
                        Replace("%5d", "rbrk").
                        Replace(".", "dot").
                        Replace("%3e", "gt").
                        Replace("%3c", "lt")
    
    Return strReturn
    
        4
  •  0
  •   Toolkit    14 年前

    我想你在找 HttpUtility.UrlEncode HttpUtility.HtmlDecode

    string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example");