urlencode() 'asterisk' (star?) 字符

2022-08-30 23:30:26

我正在测试PHPJavaurlencode()java.net.URLEncoder.encode()

爪哇岛

String all = "";
for (int i = 32; i < 256; ++i) {
    all += (char) i;
}

System.out.println("All characters:         -||" + all + "||-");
try {
    System.out.println("Encoded characters:     -||" + URLEncoder.encode(all, "utf8") + "||-");
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}

菲律宾比索

$all = "";
for($i = 32; $i < 256; ++$i)
{
    $all = $all.chr($i);
}

echo($all.PHP_EOL);
echo(urlencode(utf8_encode($all)).PHP_EOL);

所有字符似乎都以相同的方式使用两个函数进行编码,除了“星号”字符未由Java编码,并由PHP转换为%2A。如果有的话,哪种行为应该是“正确”的?

注意:我也尝试过 , 没有运气。rawurlencode()


答案 1

在URL中有一个是可以的,(但是以编码形式也可以)。*

RFC1738:统一资源定位器 (URL) 声明如下:

保留:

[...]

通常,当八位字节由字符表示和编码时,URL 具有相同的解释。但是,对于保留字符,情况并非如此:对为特定方案保留的字符进行编码可能会更改 URL 的语义。

因此,在 URL 中,只有字母数字、特殊字符“$-_.+!*'()”和用于其保留目的的保留字符才能以未编码的方式使用

另一方面,不需要编码的字符(包括字母数字)可以在URL的方案特定部分中进行编码,只要它们不用于保留目的。


答案 2

维基百科建议,当涉及到URI时,这是一个保留字符,如果不用于保留目的,则必须对其进行编码。根据 RFC3986,第 12-13 页:*

URI 包括由“保留”集中的字符分隔的组件和子组件。这些字符之所以称为“保留”,是因为它们可以(也可能不)被通用语法、每个方案特定的语法或 URI 的取消引用算法的特定于实现的语法定义为分隔符。如果 URI 组件的数据与保留字符作为分隔符的用途发生冲突,则在形成 URI 之前,必须对冲突的数据进行百分比编码。

  reserved    = gen-delims / sub-delims

  gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

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

URL RFC仍然允许字符未编码的事实是,它没有保留目的i URL,因此不必编码。因此,是否必须对其进行编码取决于您要创建的URI类型。*


推荐