195

我正在制作一个包含文章的网站,并且我需要文章根据标题具有“友好”的 URL。

例如,如果我的文章标题是"Article Test",我希望 URL 是http://www.example.com/articles/article_test

但是,文章标题(作为任何字符串)可以包含多个特殊字符,这些字符无法在我的 URL 中按字面意思输入。例如,我知道?#需要更换,但我不知道所有其他人。

URL 中允许使用哪些字符?什么是安全的?

4

13 回答 13

246

引用RFC 3986的第 2.3 节:

URI 中允许但没有保留用途的字符称为未保留字符。这些包括大写和小写字母、十进制数字、连字符、句点、下划线和波浪号。

  ALPHA  DIGIT  "-" / "." / "_" / "~"

请注意,与旧的RFC 2396相比,RFC 3986 列出的保留标点符号更少。

于 2009-03-29T21:57:33.607 回答
124

您需要注意两组字符:reservedunsafe

保留字符是:

  • 和号(“&”)
  • 美元(“$”)
  • 加号(“+”)
  • 逗号 (",")
  • 正斜杠(“/”)
  • 冒号 (”:”)
  • 分号 (";")
  • 等于 ("=")
  • 问号(“?”)
  • “在”符号(“@”)
  • 英镑(“#”)。

通常认为不安全的字符是:

  • 空间 (” ”)
  • 小于和大于 ("<>")
  • 打开和关闭括号(“[]”)
  • 打开和关闭大括号(“{}”)
  • 管道(“|”)
  • 反斜杠(“\”)
  • 插入符号(“^”)
  • 百分 (”%”)

我可能忘记了一个或多个,这导致我附和Carl V 的回答。从长远来看,您最好使用允许字符的“白名单”然后对字符串进行编码,而不是试图与服务器和系统不允许的字符保持同步。

于 2009-03-29T21:56:45.917 回答
49

始终安全

从理论上和规范来看,这些基本上在任何地方都是安全的,除了域名。对未列出的任何内容进行百分比编码,一切顺利。

    A-Z a-z 0-9 - . _ ~ ( ) ' ! * : @ , ;

有时安全

只有在特定的 URL 组件中使用时才安全;小心使用。

    Paths:     + & =
    Queries:   ? /
    Fragments: ? / # + & =
    

永远不安全

根据 URI 规范 (RFC 3986),所有其他字符都必须进行百分比编码。这包括:

    <space> <control-characters> <extended-ascii> <unicode>
    % < > [ ] { } | \ ^
    

如果考虑最大兼容性,请将字符集限制为 AZ az 0-9 - _ 。(句点仅用于文件扩展名)。

牢记上下文

即使根据规范有效,URL 仍然可能是“不安全的”,具体取决于上下文。例如包含无效文件名字符的 file:/// URL,或者在不用作分隔符时包含“?”、“=”和“&”的查询组件。这些情况的正确处理通常取决于您的脚本并且可以解决,但请记住这一点。

于 2016-11-04T03:58:39.180 回答
45

您最好只保留一些字符(白名单)而不是删除某些字符(黑名单)。

只要您正确编码,您可以在技术上允许任何字符。但是,为了回答问题的精神,您应该只允许这些字符:

  1. 小写字母(将大写转换为小写)
  2. 数字,0 到 9
  3. 破折号 - 或下划线 _
  4. 波浪号~

其他一切都有潜在的特殊意义。例如,您可能认为可以使用 +,但可以将其替换为空格。& 也很危险,尤其是在使用一些重写规则时。

与其他评论一样,请查看标准和规范以获取完整详细信息。

于 2009-03-29T21:48:44.783 回答
20

查看RFC3986 - Uniform Resource Identifier (URI): Generic Syntax,您的问题围绕着 URI 的路径组件。

    foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment
      |   _____________________|__
     / \ /                        \
     urn:example:animal:ferret:nose

引用第 3.3 节,URIsegment的有效字符类型为pchar

pchar = unreserved / pct-encoded / sub-delims / ":" / "@"

分解为:

ALPHA / DIGIT / "-" / "." / "_" / "~"

pct-encoded

"!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

":" / "@"

或者换句话说:您可以使用ASCII 表中的任何(非控制)字符,除了 /?#和。[]

这种理解得到了RFC1738 - 统一资源定位器 (URL)的支持。

于 2014-07-19T01:47:13.400 回答
12

从您描述的上下文来看,我怀疑您实际上想要做的是一种叫做“SEO slug”的东西。最普遍的已知做法是:

  1. 转换为小写
  2. 将 az 和 0-9 以外的整个字符序列转换为一个连字符 (-)(不是下划线)
  3. 从 URL 中删除“停用词”,即没有意义的可索引词,如“a”、“an”和“the”;谷歌“停用词”的广泛列表

因此,例如,一篇标题为“The Usage of !@%$* to Represent Swearing In Comics”的文章会得到一个“usage-represent-swearing-comics”的标题。

于 2009-03-29T22:09:20.940 回答
11

未保留 = ALPHA / DIGIT / "-" / "." /“_”/“~”

于 2010-12-01T22:28:38.703 回答
6

URI 的格式在RFC 3986中定义。有关详细信息,请参见第 3.3 节。

于 2009-03-29T21:46:37.767 回答
6

从 SEO 的角度来看,连字符比下划线更受欢迎。转换为小写,删除所有撇号,然后用单个连字符替换所有非字母数字字符串。剪掉开头和结尾多余的连字符。

于 2009-03-29T22:19:34.083 回答
3

我有一个类似的问题。我想要有漂亮的 URL,并得出结论,我必须在 URL 中只允许字母、数字和 - 和 _。

这很好,但后来我写了一些不错的正则表达式,我意识到它识别出所有 UTF-8 字符都不是 .NET 中的字母并且被搞砸了。这似乎是 .NET 正则表达式引擎的一个已知问题。所以我得到了这个解决方案:

private static string GetTitleForUrlDisplay(string title)
{
    if (!string.IsNullOrEmpty(title))
    {
        return Regex.Replace(Regex.Replace(title, @"[^A-Za-z0-9_-]", new MatchEvaluator(CharacterTester)).Replace(' ', '-').TrimStart('-').TrimEnd('-'), "[-]+", "-").ToLower();
    }
    return string.Empty;
}


/// <summary>
/// All characters that do not match the patter, will get to this method, i.e. useful for Unicode characters, because
/// .NET implementation of regex do not handle Unicode characters. So we use char.IsLetterOrDigit() which works nicely and we
/// return what we approve and return - for everything else.
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
private static string CharacterTester(Match m)
{
    string x = m.ToString();
    if (x.Length > 0 && char.IsLetterOrDigit(x[0]))
    {
        return x.ToLower();
    }
    else
    {
        return "-";
    }
}
于 2011-09-30T12:48:13.030 回答
1

当我通过 Ajax/PHP 将一个值返回到一个 URL 时,我发现将我的 URL 编码为一个安全的 URL 非常有用,然后页面会再次读取该 URL。

带有特殊字符的 URL 编码器的 PHP 输出&

// PHP returning the success information of an Ajax request
echo "".str_replace('&', '%26', $_POST['name']) . " category was changed";

// JavaScript sending the value to the URL
window.location.href = 'time.php?return=updated&val=' + msg;

// JavaScript/PHP executing the function printing the value of the URL,
// now with the text normally lost in space because of the reserved & character.

setTimeout("infoApp('updated','<?php echo $_GET['val'];?>');", 360);
于 2015-03-28T08:02:28.333 回答
0

我认为您正在寻找类似“ URL encoding ”的东西 - 对 URL 进行编码,以便在网络上使用它是“安全的”:

这是一个参考。如果您不想要任何特殊字符,只需删除任何需要 URL 编码的字符:

HTML URL 编码参考

于 2009-03-29T21:47:12.600 回答
-4

3-50 个字符之间。可以包含小写字母、数字和特殊字符 - 点 (.)、破折号 (-)、下划线 (_) 和比率 (@)。

于 2016-02-23T15:44:00.703 回答