urlencode()'星号'(星号?)字符

时间:2011-06-30 10:44:02

标签: java php urlencode

我正在测试 PHP urlencode() Java 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();
}

PHP

$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() - 没有运气。

3 个答案:

答案 0 :(得分:9)

在网址中有一个*是可以的(但也可以以编码形式提供)。

RFC1738: Uniform Resource Locators (URL)声明如下:

  

<强>保留:

     

[...]

     

通常,当八位字节为时,URL具有相同的解释     由字符表示并在编码时。但事实并非如此     保留字符为true:编码为a保留的字符     特定方案可能会改变URL的语义。

     

因此,只有字母数字,特殊字符"$-_.+!*'()," ,以及     用于保留目的的保留字符可以使用     URL中未编码的

     

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

答案 1 :(得分:6)

Wikipedia suggests *是一个保留字符,当涉及到URI时,如果不用于保留目的,则必须进行编码。根据{{​​3}},第12-13页:

  

URI包括由分隔的组件和子组件    “保留”集中的字符。这些字符被调用    “保留”因为它们可能(或可能不)被定义为分隔符    通用语法,每种特定于方案的语法,或者由    URI的解除引用算法的特定于实现的语法。    如果URI组件的数据与保留的数据冲突    字符作为分隔符的目的,那么冲突的数据必须是    在URI形成之前进行百分比编码。

  reserved    = gen-delims / sub-delims

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

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

RFC3986仍然允许*字符未编码的事实是具有保留目的i网址,因此不会必须进行编码。所以你必须编码或不编码它取决于你正在创建什么类型的URI。)

答案 2 :(得分:2)

Javadoc of URLEncoder指的是HTML规范:

  

此类包含用于将String转换为application/x-www-form-urlencoded MIME格式的静态方法。有关HTML表单编码的更多信息,请参阅HTML规范。

HTML4对于这个问题还不太清楚,并提到RFC1738,这是由aioobe引用的:

  

转义控件名称和值。空格字符被替换为'+',然后保留字符被转义,如[RFC1738],第2.2节中所述:非字母数字字符被'%HH'替换,百分号和两个十六进制数字代表ASCII代码字符。换行符表示为“CR LF”对(即'%0D%0A')。

但是,HTML5直接指出*不应编码:

  
      
  • 如果角色不在U + 0020范围内, U + 002A ,U + 002D,U + 002E,U + 0030到U + 0039,U + 0041到U + 005A ,U + 005F,U + 0061至U + 007A
      用字符串替换字符如下:
      ...
  •   
  • 否则
      保留角色。
  •