【问题标题】:urlencode() the 'asterisk' (star?) characterurlencode() '星号'(星号?)字符
【发布时间】:2011-09-25 21:19:29
【问题描述】:

我正在测试 PHP urlencode()Java java.net.URLEncoder.encode()

Java

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

【问题讨论】:

标签: java php urlencode


【解决方案1】:

Javadoc of URLEncoder指的是HTML规范:

此类包含将字符串转换为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
    将字符替换为如下格式的字符串:
    ...
  • 否则
    让角色保持原样。

【讨论】:

    【解决方案2】:

    可以在 URL 中使用 *,(但也可以使用编码形式)。

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

    保留:

    [...]

    通常,当八位字节是 URL 时,URL 具有相同的解释 由一个字符表示以及它何时编码。然而,这并不是 保留字符为真:编码为 a 保留的字符 特定的方案可能会改变 URL 的语义。

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

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

    【讨论】:

    【解决方案3】:

    Wikipedia suggests* 在涉及 URI 时是一个保留字符,如果不用于保留目的,则必须对其进行编码。根据RFC3986,第 12-13 页:

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

      reserved    = gen-delims / sub-delims
    
      gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
    
      sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
                  / "*" / "+" / "," / ";" / "="
    

    the URL RFC 仍然允许* 字符未编码的事实是,没有在 URL 中具有保留用途,因此不必编码. 所以你是否必须对其进行编码取决于你正在创建什么样的 URI。)

    【讨论】:

    • 能否请您附上页面中指出应该对* 进行编码的引用?
    • @aioobe:完成。 URL 和 URI RFC 之间似乎存在差异,其中 URL RFC 实际上覆盖了编码 * 的 URI RFC 要求。因此,答案实际上取决于您要创建的 URI 类型。
    • urlencodejava.net.URLEncoder 表示他在寻找一个 URL。
    • RFC3986 明确声明它更新了 RFC1738,所以我认为任何不一致都会得到解决,有利于 RFC3986。 RFC3986 说 URL 是 URI 的一个例子,如果 URI 必须有星号编码,那么 URL 也应该有。但各种在线工具的做法不同(参见,例如,meyerweb.com/eric/tools/dencoderurl-encode-decode.com/.
    猜你喜欢
    • 2013-08-04
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    相关资源
    最近更新 更多