我正在使用mod_rewrite将漂亮的URL重写为Spring 2.5应用程序支持的表单。
e.g. /category/cat1?q=x => /controller?category=cat1&q=x
但是,从我的控制器我想知道请求来自的原始URL(所以如果需要我可以生成一个链接)。所有页面都需要这种方法,因此很难进行硬编码。
如何从我的控制器访问原始路径+查询字符串?
我尝试使用$ 0来包含完整路径,但这不包括查询字符串。我不能只追加路径和查询字符串,因为这会导致路径的某些部分被添加为参数/category/cat1?category=cat1&q=x
注意添加了不需要的&category=cat1
参数,这会导致URL为no从浏览器发送的较长匹配。
我希望mod_rewrite允许我引用完整的URL并将其编码为参数,因此我的规则可能如下所示:
RewriteRule /category/(.+)
/controller?category=$1&_originalUrl=${escape:$0}?${escape:<original query string>}
[QSA]
使用我的原始示例,传递给我的控制器的最终结果将是:
/controller?category=cat1&_originalUrl=%2Fcategory%2Fcat1%3Fsearch%3Dx&search=x
重要的部分是&_originalUrl
的值%2Fcategory%2Fcat1%3Fsearch%3Dx
,其非转义版本为/category/cat1?q=x
(从浏览器发送的原始请求网址)。
欢迎任何建议,提前谢谢!
答案 0 :(得分:8)
可以使用RewriteCond
对查询进行测试,因为RewriteRule
仅测试URL path。请参阅Jonathan Feinberg的示例,了解如何做到这一点。
但您也可以设置QSA flag,旧查询会自动附加到新查询中:
RewriteRule ^/category/([^/]+)$ /controller?category=$1 [QSA]
修改回复您对此问题的评论:如果您想获取初始请求的URI路径和查询,则需要从request line中提取它( THE_REQUEST 变量):
RewriteCond %{THE_REQUEST} ^[A-Z]+\ ([^\s]+)
RewriteRule ^/category/([^/]+)$ /controller?category=$1&_originalUrl=%1 [QSA]
但在大多数语言中,都有一个环境变量具有完全相同的信息。
答案 1 :(得分:1)
您必须在初始的单独步骤中捕获查询字符串。
RewriteCond %{query_string} ^q=([^&]+)
RewriteRule ^/category/(cat1)$ /controller?category=$1&q=%1
等
答案 2 :(得分:0)
您是否可以使用主机标头?很抱歉这么模糊,但上次我不得不这样做是使用PHP(urgh,不要问),我想我们是怎么做的 - 例如REQUEST_URI(http://www.askapache.com/htaccess/mod_rewrite-variables-cheatsheet.html)
您也可以在重写(http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html)
中设置主机头例如:
ReWriteRule /category/(cat1)?q=(x) /controller?category=$1&q=$2 [E=FOO:....]
(不,我完全不是一个mod-rewrite ninja)