当前位置: 首页 > 知识库问答 >
问题:

什么时候应该在HTTP URL中编码星号?

葛和志
2023-03-14

根据RFC1738,星号(*)“可在URL内未编码使用”:

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

然而,w3。org的命名和寻址材料说,星号“保留用于在特定方案中具有特殊意义”,并暗示它应该被编码。

另外,根据RFC3986,URL是URI:

术语“统一资源定位器”(URL)是指URI的子集,其除了标识资源之外,还通过描述其主要访问机制(例如,其网络“位置”)提供定位资源的方法。

它还规定星号为“子delim”,是“保留集”的一部分,并且:

产生URI的应用程序应该对与保留集中的字符相对应的数据八位字节进行百分比编码,除非URI方案特别允许这些字符表示该组件中的数据。

它还明确指定更新RFC1738。

我认为所有这些都要求在URL中编码星号,除非它们用于URI方案定义的特殊用途。

RFC1738是HTTP URI方案的规范参考吗?它是否以某种方式免除了星号的编码,或者由于RFC3986,它在这方面已经过时了?

维基百科说,“当字符没有保留用途时,不需要对其进行百分比编码。”RFC1738是否删除星号的保留用途?

在这个问题上,各种资源和工具似乎存在分歧。

PHP的urlencoderawurlencode--后者声称遵循RFC3986--确实编码星号。

但是,JavaScript的escapeencodeURIComponent不编码星号。

而且Java的URLEncoder不编码星号:

特殊字符“,“-”、“*”和“u”保持不变。

流行的在线工具(谷歌搜索“在线网址编码器”的前两个结果)也不编码星号。URL编码和解码工具特别指出,“[保留的字符只能在特定情况下编码。”它接着将星号和&号列为保留字符。它编码与号,但不编码星号。

Stack Exchange社区中的其他类似问题似乎有陈旧、不完整或不令人信服的答案:

  • urlencode()星号(星?)这个问题强调了Java和PHP对星号的处理方式的不同,并询问哪个是“正确的”。接受的答案仅参考RFC1738,未提及最近的RFC3986和解决冲突。另一个答案承认了这一差异,并指出星号与其他URI不同,但它没有为这一结论提供具体的权威
  • URL可以有星号吗?一个答案只引用了旧的RFC1738,而被接受的答案意味着它在用作分隔符时是可以接受的,我们假定它是“保留用途”
  • 我可以在URL中使用星号吗?公认的答案似乎不鼓励使用星号,但没有明确规定使用星号的规则。另一个答案是你可以使用星号“因为它是一个保留字符”。但这不是只有当你把它用于保留的目的时才是真的吗
  • 转义url中的特殊字符一个答案指出“是否必须在url中编码星号存在一些歧义”。我试图用这个问题来解决这个模棱两可的问题
  • Spring UriUtils和RFC3986此问题注意到UriUtil的encodeQueryParam声称遵循RFC3986,但它不编码星号。截至2014-08-01 CDT下午12:50,该问题尚无答案
  • 如何用JavaScript编码URL?这似乎是关于堆栈溢出的规范JavaScript URL编码问题,尽管答案指出星号被排除在各种方法之外,但它们没有说明是否应该使用星号

考虑到所有这些,什么时候应该在HTTP URL中编码星号?

共有1个答案

常英毅
2023-03-14

##简短回答

URL语法的当前定义表明,您永远不需要对URL的路径、查询或片段组件中的星号字符进行百分比编码。

正如@Riley Major所指出的,RFC即HTTP 1.1对URL语法的引用已经被RFC3986所淘汰,它对于星号的使用不像最初引用的RFC那样黑白分明。

在HTTP 1.1 URL中不需要对星号进行编码,因为在RFC2396中,*被列为“无保留字符”,用于定义HTTP 1.1中的URI语法。URL的路径组件中允许使用无保留字符。

2.3. 无保留字符

URI中允许但没有保留用途的数据字符称为unreserved。其中包括大写和小写字母、十进制数字以及一组有限的标点符号和符号。

   unreserved  = alphanum | mark

   mark        = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"

可以在不更改URI语义的情况下转义未保留的字符,但除非在不允许未转义字符出现的上下文中使用URI,否则不应这样做。

RFC3986修改RFC2396,使星号成为保留字符,原因是它“通常不安全解码”。我对这个RFC的理解是,未编码的星号字符允许出现在URL的路径、查询和片段组件中,因为这些组件不指定星号作为分隔符(2.2.保留字符):

这些字符被称为“保留”,因为它们可能(也可能不)被通用语法定义为分隔符。。。如果URI组件的数据与保留字符作为分隔符的用途相冲突,则在形成URI之前,必须对冲突数据进行百分比编码。

此外,3.3 Path确认保留字符的子集(sub delims)可以在路径段(路径组件的一部分被/分解)中未编码地使用:

除了点段(“.”)及“.”)在分层路径中,一般语法认为路径段是不透明的。URI生成应用程序通常使用段中允许的保留字符。。。例如,分号(“;”)和等于(“=”)保留字符通常用于分隔适用于该段的参数和参数值。逗号(“,”)保留字符通常用于类似目的。例如,一个URI生产者可能使用诸如“name;v=1.1”之类的段来表示对“name”版本1.1的引用,而另一个URI生产者可能使用诸如“name,1.1”之类的段来表示相同的引用。

HTTP 1.0引用RFC1738来定义URL语法,通过一系列更新和废弃,这意味着它使用与HTTP 1.1相同的RFC来定义URL语法。

就向后兼容性而言,RFC1738将星号指定为保留字符,尽管HTTP 1.0实际上没有为URL的路径组件中的未编码星号定义任何特殊含义,但如果使用星号,它不应破坏任何内容。这意味着您仍然可以在指向最旧系统的URL中使用星号。

顺便说一下,星号字符在两个HTTP规范中的请求URI中确实有特殊的含义,但是不可能用HTTP URL来表示它:

星号“*”表示请求不适用于特定资源,而适用于服务器本身,并且仅当所使用的方法不一定适用于资源时才允许。一个例子是

   OPTIONS * HTTP/1.1

免责声明:我只是自己阅读和解释这些RFC,所以我可能是错的。

 类似资料:
  • 问题内容: 在工作中进行大量重构的中间,我希望引入stdClass *作为从函数返回数据的一种方式,并且我试图找到非主观论据来支持我的决定。 是否有任何情况下最好使用一种而不是另一种? 使用stdClass而不是数组有什么好处? 有人会说,函数必须尽可能少且特定,才能返回一个值。 我决定使用stdClass是暂时的,因为从长远来看,我希望为每个进程找到正确的Value Objects。 问题答案:

  • 问题内容: 我知道他们两个都禁用了Nagle的算法。 我什么时候应该/不应该使用它们中的每一个? 问题答案: 首先,不是所有人都禁用Nagle的算法。 Nagle的算法用于减少有线中更多的小型网络数据包。该算法是:如果数据小于限制(通常是MSS),请等待直到收到先前发送的数据包的ACK,同时累积用户的数据。然后发送累积的数据。 这将对telnet等应用程序有所帮​​助。但是,在发送流数据时,等待A

  • 问题内容: 在该类中,有两个字符串,和。 有什么不同?我什么时候应该使用另一个? 问题答案: 如果你的意思是和则: 用于在文件路径列表中分隔各个文件路径。考虑在上的环境变量。您使用a分隔文件路径,因此在上将是;。 是或用于拆分到特定文件的路径。例如在上,或

  • 问题内容: 在集成我以前从未使用过的Django应用程序时,我发现了用于定义类中函数的两种不同方式。作者似乎非常有意地使用了它们。第一个是我自己经常使用的: 另一个是我不使用的,主要是因为我不知道何时使用它,以及什么用途: 在Python文档中,装饰器的解释如下: 类方法将类作为隐式第一个参数接收,就像实例方法接收实例一样。 所以我想指的是自己(而不是实例)。我不完全理解为什么会这样,因为我总是可

  • 问题内容: 我已经用python编程了大约两年了。主要是数据资料(熊猫,mpl,numpy),还有自动化脚本和小型Web应用程序。我试图成为一个更好的程序员,并增加我的python知识,而困扰我的一件事是我从未使用过一个类(除了为小型Web应用程序复制随机烧瓶代码外)。我通常理解它们是什么,但是我似乎无法为为什么在一个简单的函数中需要它们的问题而wrap之以鼻。 为了使我的问题更具针对性:我编写了

  • 问题内容: 我看过各种文章,但我仍然不知道为什么不应该使用它。请让我知道您的想法。 问题答案: 我发现有必要在错误的设计中使用instanceof提示。可以肯定的是,将会出现一个大型,复杂的开关风格的构造。在我看到的其他大多数情况下,我们应该使用多态而不是instanceof。请参阅策略模式。(相关的使用示例) 我唯一需要使用的是实现时。