斜杠 ("/") 是不是等同于 HTTP URL 路径部分中的编码斜杠 ("%2F")
Posted
技术标签:
【中文标题】斜杠 ("/") 是不是等同于 HTTP URL 路径部分中的编码斜杠 ("%2F")【英文标题】:Is a slash ("/") equivalent to an encoded slash ("%2F") in the path portion of an HTTP URL斜杠 ("/") 是否等同于 HTTP URL 路径部分中的编码斜杠 ("%2F") 【发布时间】:2010-12-29 18:01:34 【问题描述】:我有一个网站以不同方式处理 URL 的路径部分(不是查询字符串)中的“/”和“%2F”。根据 RFC 或现实世界,这是一件坏事吗?
我之所以这么问,是因为我一直对我使用的 Web 框架(Ruby on Rails)以及它下面的层(Passenger、Apache,例如,我必须为 Apache 启用“ALLOW_ENCODED_SLASHES”)感到惊讶。我现在倾向于完全摆脱编码斜杠,但我想知道是否应该提交错误报告,因为我发现涉及编码斜杠的奇怪行为。
至于为什么我首先有编码的斜线,基本上我有这样的路线:
:controller/:foo/:bar
其中 :foo 类似于可以包含斜杠的路径。我认为最直接的做法就是 URL 转义 foo
,这样路由机制就会忽略斜杠。现在我有疑问了,很明显框架并不真正支持这一点,但根据 RFC,这样做是错误的吗?
以下是我收集到的一些信息:
RFC 1738(网址):
通常,当八位位组由字符表示时和编码时,URL 具有相同的解释。但是,对于保留字符,情况并非如此:对为特定方案保留的字符进行编码可能会改变 URL 的语义。
RFC 2396(URI):
这些字符被称为“保留”,因为它们在 URI 组件中的使用仅限于它们的保留用途。如果 URI 组件的数据会与保留用途发生冲突,则必须在形成 URI 之前对冲突数据进行转义。
(这里的转义是否意味着编码保留字符以外的其他东西?)
RFC 2616 (HTTP/1.1):
“保留”和“不安全”集中的字符(参见 RFC 2396 [42])等价于它们的“%”HEX HEX“编码。
Rails 也有 this bug report,他们似乎期望编码的斜杠表现不同:
是的,我希望得到不同的结果,因为它们指向不同的资源。
它在根目录中寻找文字文件 'foo/bar'。非转义版本正在查找目录 foo 中的文件 bar。
从 RFC 中可以清楚地看出,原始字符与编码字符对于非保留字符是等价的,但是对于保留字符又是什么情况呢?
【问题讨论】:
相关:***.com/q/14631200/1591669 使用前端控制器的 php 用户:$_GET & $_REQUEST 已经被 urldecode。这可能会导致斜杠出现问题,因为您将无法分辨什么是斜杠以及什么是 %2F。如果您绝对需要查看发送的请求,请查看 $_SERVER['REQUEST_URI']。另见urldecode()@php.net 相关帖子 - How to URL Encode a Backslash with R/RCurl 【参考方案1】:根据您收集的数据,我倾向于说 uri 中编码的“/”在应用程序/cgi 级别再次被视为“/”。
也就是说,例如,如果您使用带有mod_rewrite
的apache,它将不会匹配期望斜杠与其中带有编码斜杠的URI 的模式。
但是,一旦调用了适当的模块/cgi/... 来处理请求,就由它来进行解码,例如,检索包含斜杠作为 URI 的第一个组成部分的参数。
如果您的应用程序随后使用此数据来检索文件(其文件名包含斜杠),那可能是一件坏事。
总而言之,我发现在“/”或“%2F”中看到行为差异是完全正常的,因为它们的解释将在不同的级别上完成。
【讨论】:
这也是我一直在想的。不幸的是,在现实世界中似乎没有太多支持这样做。我现在会继续工作,但如果我要重新开始,我会尝试不同的转义机制。 @user85509 我想知道我是否应该提交错误报告,如果我发现涉及编码斜杠的奇怪行为。 – 请在每次观察到不符合 RFC 的行为时进行其中明确指出/
作为 保留 字符与其百分比编码形式 %2F
不同。【参考方案2】:
%2F
与 /
的故事是,根据最初的W3C recommendations,斜线«必须暗示一个层次结构»:
斜杠(“/”,ASCII 2F hex)字符保留用于分隔 的关系是分层的子串。这使得部分 URI 的形式。
示例 2
URI
http://www.w3.org/albert/bertram/marie-claude
和
http://www.w3.org/albert/bertram%2Fmarie-claude
不相同,因为在第二种情况下,编码的斜杠不 具有等级意义。
【讨论】:
查询呢?就像,查询没有层次结构。它们只是变量。 W3C 推荐没有解释,这是小事。【参考方案3】:我还有一个网站,其中包含许多带有 urlencoded 字符的 url。我发现许多 Web API(包括 Google 网站管理员工具和几个 Drupal 模块)都会跳过 urlencoded 字符。许多 API 在其过程中的某个时间点自动解码 url,然后将结果用作 URL 或 html。当我发现其中一个问题时,我通常会对该 API 的结果进行双重编码(将 %2f 转换为 %252f)。但是,这会破坏其他不需要双重编码的 API,因此这不是一个通用的解决方案。
就我个人而言,我会尽可能多地删除 URL 中的特殊字符。
另外,我在我的 URL 中使用了不依赖于 urldecoding 的 id 编号:
example.com/blog/my-amazing-blog%2fstory/昨天
变成:
example.com/blog/12354/my-amazing-blog%2fstory/yesterday
在这种情况下,我的代码仅使用 12354 来查找文章,而我的系统会忽略 URL 的其余部分(但仍用于 SEO。)此外,此数字应出现在未使用的 URL 组件之前。这样,即使 %2f 被错误解码,url 仍然可以工作。
此外,请务必使用规范标签,以确保 url 错误不会转化为重复的内容。
【讨论】:
这个方法似乎对 reddit.com 很有效。【参考方案4】:如果您使用 Tomcat,请在 VM 属性中添加“-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true”。
https://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html#Security
【讨论】:
【参考方案5】:如果:foo
的自然形式包含斜杠怎么办?你不希望它是那推荐试图保留的区别吗? It specifically notes,
与 unix 和其他磁盘操作系统文件名约定的相似性应视为纯属巧合,不应将 URI 解释为文件名。
如果有人正在为备份程序构建在线界面,并希望将路径表示为 URL 路径的一部分,那么在文件路径中编码斜杠是有意义的,因为那是 not 确实是资源层次结构的一部分——更重要的是,路由。 /backups/2016-07-28content//home/dan/
在双斜杠中丢失了文件系统的根。正如我所读到的,转义斜线是区分的适当方法。
【讨论】:
【参考方案6】:encodeURI()
/decodeURI
和 encodeURIComponent()
/decodeURIComponent
是处理这个问题的实用函数。在此处阅读更多信息https://stackabuse.com/javascripts-encodeuri-function/
【讨论】:
以上是关于斜杠 ("/") 是不是等同于 HTTP URL 路径部分中的编码斜杠 ("%2F")的主要内容,如果未能解决你的问题,请参考以下文章
在 sklearn RandomForestClassifier 中,class_weight=None 是不是等同于 class_weight="balanced_subsample&qu