当用户首次访问我们的服务器时,我们希望捕获有关传入请求的一些信息:GET
参数、Referer
标头等。一般的想法是,当我们收到与某些RewriteCond
条件匹配的传入请求时(没有 cookie,没有特定GET
参数以防它们不接受 cookie 等),我们使用RewriteRule
with[P]
透明地将请求代理到 servlet(实际上是 Spring 控制器,如果这很重要),它将分析传入请求,然后发送带有新 cookie 集的 302,以将用户重定向到最初请求的 URL。也就是说,
- 用户请求
/foo.html
mod_rewrite
检测到这是用户的第一个请求(没有 cookie,没有GET
标志参数)- A
RewriteRule
与[P]
代理/my/spring/controller
- Servlet 分析请求并以 302 做出响应
Location: /foo.html
。
前三个步骤很简单。问题是,在第四步中,servlet 不知道/foo.html
曾经请求过什么,这意味着 (a) 它无法记录这种情况(业务需求)和 (b) 它不知道要重定向到哪里。我们可以看到哪个服务器被要求X-Forwarded-Host
等人,但查看请求 URL 只显示/my/spring/controller
。
那么,我们想要实现的理想是代理传递不仅对客户端透明,而且对接收 servlet 也同样透明。
一种选择是使用类似 的内容将 URL 传递到环境变量中[E=FOO:REQUEST_URI]
。但是,这会增加 servlet 的复杂性,而且我不清楚请求是否没有改变。servlet 的目的是分析来自客户端的请求,最好是 Apache 未改变的请求。如果mod_rewrite
更改了请求 URL,我是否可以相信请求的所有其他方面都没有改变?
答案1
信任 mod_rewrite,如果偏执的话,将你感兴趣的东西作为一系列 CGI 变量传递给你的小程序,例如
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{HTTP_COOKIE} !.........
RewriteRule /?foo.html /my/spring/controller?theRequest=%{THE_REQUEST}&requestURI=%{REQUEST_URI}&referer=%{HTTP_REFERER} [P,L]