RewriteRule 仅包含 REQUESTI_URI 的最后一部分

RewriteRule includding only last part of REQUESTI_URI

<LocationMatch /foo/>
 ProxyPreserveHost On
 RewriteEngine on
 RewriteCond %{HTTP:Upgrade} websocket [NC]
 RewriteCond %{HTTP:Connection} upgrade [NC]
 RewriteRule .* "ws://192.168.0.101:1234%{REQUEST_URI}" [P]

当客户端连接到

ws://www.example.com/foo/whatever_arbitrary_random

效果很好,但结果是

ws://192.168.0.101:1234/foo/whatever_arbitrary_random

我怎样才能去掉 /foo/ 所以结果会是

ws://192.168.0.101:1234/whatever_arbitrary_random

客户端必须仍然需要连接到 /foo/ 才能触发这个

编辑:我找到了方法,将最后一行替换为

RewriteRule ([^/]+)/?$ ws://192.168.0.101:1234/ [P,L]

但请阅读建议不要在某个位置执行此操作的第一个答案

您不应在 <Location>(和 <LocationMatch>)容器内使用 mod_rewrite 指令。

更新:the Apache docs for the RewriteRule directive 所述:

Although rewrite rules are syntactically permitted in <Location> and <Files> sections (including their regular expression counterparts), this should never be necessary and is unsupported. A likely feature to break in these contexts is relative substitutions.

<Location> 部分很晚才合并。当在 <Location> 部分内使用时,RewriteRule 指令匹配绝对文件系统路径,而不是通常预期的 URL 路径。

如果 .htaccess 覆盖被禁用,那么您可以在适当的 <Directory> 容器内这样做:

<Directory /path/to/foo>
    # Disable .htaccess overrides if not already
    AllowOverride None

    ProxyPreserveHost On

    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule .* ws://192.168.0.101:1234/[=10=] [P]
</Directory>

反向引用[=23=]自然排除/foo/.


更新:

RewriteRule ([^/]+)/?$ ws://192.168.0.101:1234/ [P,L]

这只匹配最后一段路径,并不严格匹配/foo/之后的所有内容。这可能会或可能不会,具体取决于您的要求。例如。它只会将 /foo/bar/baz 的请求重定向到 /baz,而不是 /bar/baz.

正则表达式确实应该被锚定。但是,您可能以这种方式编写它,因为该指令位于 <Location> 部分内并且匹配绝对文件路径,而不是请求的 URL-path.

顺便说一句,当与 P 一起使用时,您不需要 L 标志 - 这是隐含的。


上述的替代方法...您不需要在 目录 上下文中使用这些指令(即在 <Directory><Location> 节)。您可以将这些规则直接放在 <VirtualHost> 容器中(一个 virtualhost 上下文),在这种情况下,它们应该这样写:

ProxyPreserveHost On

RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/foo/(.*) ws://192.168.0.101:1234/ [P]