mod_rewrite:将路径和查询字符串 URL 作为参数传递

Posted

技术标签:

【中文标题】mod_rewrite:将路径和查询字符串 URL 作为参数传递【英文标题】:mod_rewrite: Pass the path & query string URL as a parameter 【发布时间】:2010-12-25 08:35:47 【问题描述】:

我正在使用 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 不再匹配发送来自浏览器。

我希望 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

重要的部分是&amp;_originalUrl 的值,它应该是%2Fcategory%2Fcat1%3Fsearch%3Dx,在其非转义版本中是/category/cat1?q=x(从浏览器发送的原始请求 URL)。

欢迎任何建议,在此先感谢!

【问题讨论】:

我在tools.cherrypy.org/wiki/ModRewrite 发现了一个转义函数 $escape:$1 现在我需要弄清楚如何附加路径和原始查询字符串。 $escape:$0$escape: 在单独的参数中接收原始路径和查询字符串将是一个合适的解决方案。例如&_originalPath=$escape:$0&_originalQueryString=$escape: 是我不知道如何获取的部分。 嗨,有一个类似的问题要解决,但似乎 int:escape 重写映射无法解决问题:它不是 url 编码(比如将 / 变成 %2F,& 到 %26等),只是在 url 中不允许编码字符。我能看到的最后一个选项是使用外部映射程序,但它只会遇到更多麻烦......或者将“;original_qs = ”附加到重写的url 【参考方案1】:

有可以使用的主机头吗?抱歉这么含糊,但上次我不得不这样做是使用 php(呃,别问),我认为我们就是这样做的 - 例如 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 重写忍者)

【讨论】:

感谢您的回复,我最初的问题有点含糊。我不关心主机名,只关心原始路径和查询字符串。我已经相应地更新了问题。【参考方案2】:

查询只能用RewriteCond 测试,因为RewriteRule 只测试URL path。请参阅 Jonathan Feinberg 的示例如何做到这一点。

但您也可以只设置QSA flag,旧查询会自动附加到新查询:

RewriteRule ^/category/([^/]+)$ /controller?category=$1 [QSA]

编辑    回复您对此问题的评论:如果您想获取初始请求的 URI 路径和查询,您需要从 request line 中提取它(THE_REQUEST em> 变量):

RewriteCond %THE_REQUEST ^[A-Z]+\ ([^\s]+)
RewriteRule ^/category/([^/]+)$ /controller?category=$1&_originalUrl=%1 [QSA]

但在大多数语言中,都有一个具有相同信息的环境变量。

【讨论】:

感谢 QSA 示例。抱歉,我的示例不是很准确,我正在使用 [QSA] 将原始查询字符串自动附加到重写的 URL。我想要实现的是获取用户在浏览器中看到的原始(未重写)路径+查询字符串,并将其作为编码参数传递给我的控制器。 @richardpaul:在这种情况下,您应该从请求行中提取该信息:RewriteCond %THE_REQUEST ^[A-Z]+\ ([^\s]+) RewriteRule ^/category/([^/]+)$ /controller?category=$1&amp;_originalUrl=%1【参考方案3】:

您必须在初始的单独步骤中捕获查询字符串。

RewriteCond %query_string ^q=([^&]+)
RewriteRule ^/category/(cat1)$ /controller?category=$1&q=%1

等等

【讨论】:

谢谢,但我需要捕获整个查询字符串,并且它需要采用通用方式(我不知道将传递哪些参数)。根据 Gumbo 的建议,我已更新示例以使用 QSA。 我的回答中有足够的信息让您走上正确的道路。祝你好运。

以上是关于mod_rewrite:将路径和查询字符串 URL 作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章

Mod_rewriting 将查询字符串写入 swf 文件

mod_rewrite:从 URL 中删除查询字符串?

如何从 mod_rewrited url 查询字符串中获取

如何根据查询字符串在 apache mod_rewrite 中禁止 url?

使用 mod_rewrite 重定向查询字符串(反之亦然)

mod_rewrite 匹配编码的 URL