即使没有提供NE标志,mod_rewrite也不会对特殊字符进行编码?

时间:2013-06-14 04:22:37

标签: apache mod-rewrite url-encoding

很明显,从apache文档中我看到了NE标志的以下描述: https://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_ne

  

默认情况下,特殊字符,例如&例如,将转换为等效的十六进制代码。使用[NE]标志可以防止这种情况发生。

     

RewriteRule ^ / anchor /(.+)/bigpage.html#$1 [NE,R]

     

以上示例将/ anchor / xyz重定向到/bigpage.html#xyz。省略[NE]将导致#被转换为其等效的十六进制代码%23,这将导致404 Not Found错误条件。

但是,我已经看到很多例子,你只需要像这样放一个RewriteRule:

RewriteRule ^(。*)$ http://www.mydomain.com/?foo=bar&jee=lee [L,R]

如果你检查重定向后发送给服务器的最终请求,它只是这个相同的普通字符串,没有任何uri编码。如果我进行更多实验,似乎uri-encoding只发生在mod_rewrite内,如果源字符串在查询字符串部分中有一些特殊字符,比如源是originaldomain.com/?foo%5d=6

然后mod_rewrite将尝试通过编码"%"将其重写为mydomain.com/?foo%255d=6。进入"%25",如果未提供NE。但请注意,如果我省略"?"在我的原始请求中,编码不会发生。

这让我对大多数网站和文档中描述的内容感到困惑,除非我以完全错误的方式理解这个概念。

另外,我很想知道一般来说,浏览器和mod_rewrite用来决定是否要编码某些字符的经验法则是什么。在我看来,浏览器往往不编码任何东西,除非它发现很难或没有意义发送在浏览器中输入的内容,这是正确的吗?另外,如果有人能够在整个过程中提供完整的工作流程,以确定在浏览器中键入域以实际获取页面时所有编码和解码的发生时间和地点?

1 个答案:

答案 0 :(得分:1)

关于URI的一般“经验法则”“关于所有编码和解码发生的时间和地点的完整工作流程可以在{{ 3}}:

  

通用语法使用斜杠(“/”),问号(“?”)和
  数字符号(“#”)字符用于分隔为
的组件   对于泛型解析器的层次解释很重要   标识符

简而言之,大多数浏览器使用的#符号被视为相对引用。例如,您可以在页面上添加指向id的链接:

http://www.example.com/mypage.html#some_div_id

因此,Apache并不期望这是服务器端的事情。因此,默认情况下,当您进行重写时,它的url编码(它们的术语正在转义)hash符号将其传递给它。 (根据RFC,它试图保护你自己。)

[NE]或noescape标志基本上阻止了默认的网址编码。

同样根据RFC:

  

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

此外,第1.2.3节

  

因为相对引用只能在a的上下文中使用   分层URI,新URI方案的设计者应该使用语法   与通用语法的分层组件一致,除非   有令人信服的理由禁止内部的相对引用   那个计划。