URL片段中的百分号是否必须进行百分编码?
URL片段中百分号的编码与浏览器行为解析
这个行为是正确的,它并没有违反RFC 3986的规范,只是规则的适用范围需要明确。
核心逻辑:URL片段的特殊处理规则
URL片段(即#之后的部分)属于客户端侧的标识,不会被发送到服务器,因此它的编码和解析规则和URI的其他部分(路径、查询参数等)完全不同:
- RFC 3986规定,片段允许包含除
#之外的任意字符,包括未编码的%——因为%在片段中没有特殊语义,不需要作为编码标识来处理。 - 浏览器处理片段时,会先对片段内容进行百分解码,再用解码后的字符串匹配页面中的元素ID。这就直接解释了你的测试结果:
#%解码后是%,匹配<p id="%">;#%25解码后是%25,匹配<p id="%25">;#%2525解码后同样是%25,所以也会匹配<p id="%25">。
和RFC 3986表述的矛盾澄清
你引用的RFC 3986内容:
因为百分号("%")是百分编码八位组的标识,若要将其作为URI中的数据使用,必须编码为"%25"。
这条规则仅适用于URI中需要被服务器解析的部分(比如路径、查询参数)——这些部分的%会被服务器当作编码标识,所以如果要表示普通的%字符,必须转义为%25。但片段完全在客户端处理,不受这条规则约束。
验证代码
p:target { background-color: yellow; }
<p id="%">Buy today</p> <p id="%25">and get 25% off!</p> <a href="#%">http://server/#%</a> <a href="#%25">http://server/#%25</a> <a href="#%2525">http://server/#%2525</a>
内容的提问来源于stack exchange,提问作者Heiko Theißen
相关产品推荐
相关产品推荐

