我正在测试 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()
- 没有运气。
答案 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
用字符串替换字符如下:
...- 否则
保留角色。