为什么RewriteRule ^ page /?$ page.php [L]匹配site.com/page//

时间:2021-10-21 11:03:56
RewriteEngine on
RewriteRule ^page/?$ page.php [L]

This ends up matching the url www.site.com/page// but internally it acts differently than www.site.com/page/ because the stylesheets and images no longer appear properly. Am I doing something wrong or is this just something I need to deal with if I don't want to go through a lot of trouble?

这最终匹配网址www.site.com/page//但在内部它的行为与www.site.com/page/不同,因为样式表和图像不再正确显示。我做错了什么,或者这只是我需要处理的事情,如果我不想经历很多麻烦的话?

To me it looks like it should only match www.site.com/page or www.site.com/page/

对我来说,它看起来应该只匹配www.site.com/page或www.site.com/page/

1 个解决方案

#1


Apache strips the empty path segment. So /path// is treated as /path/. But your browser doesn’t so relative URLs are resolved using /path//.

Apache剥离空路径段。所以/ path //被视为/ path /。但是您的浏览器不会使用/ path //解析相对URL。

If you want to remove the multiple slashes, you can use the following rule:

如果要删除多个斜杠,可以使用以下规则:

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /(([^/\ ]+/)*)/+([^\ ]*)
RewriteRule ^ /%1%3 [L,R=301]

Explaination

Despite Apache removes empty path segments internal, the THE_REQUEST environment variable (holding the HTTP request line) stays untouched. So we can use this value to check for multiple slashes.

尽管Apache删除了内部的空路径段,但THE_REQUEST环境变量(保持HTTP请求行)保持不变。所以我们可以使用这个值来检查多个斜杠。

  • ^[A-Z]+\ / matches the request method, the following space and the first slash character of the URI path.
  • ^ [A-Z] + \ /匹配请求方法,以下空格和URI路径的第一个斜杠字符。

  • (([^/\ ]+/)*) matches all following non-empty path segments (foo/, foo/bar/, foo/bar/baz/, etc.) or nothing, if there are none.
  • (([^ / \] + /)*)匹配所有后续的非空路径段(foo /,foo / bar /,foo / bar / baz /等),如果没有则匹配。

  • /+ matches the empty path segments as the character before this slash is always another slash (see the expressions before).
  • / +匹配空路径段,因为此斜杠之前的字符始终是另一个斜杠(请参阅前面的表达式)。

  • ([^\ ]*) matches the rest of the URI (that may contain further empty path segments).
  • ([^ \] *)匹配URI的其余部分(可能包含更多空路径段)。

Example: Let’s say we request http://example.com/foo/bar//baz, the request line will look like this:

示例:假设我们要求http://example.com/foo/bar//baz,请求行将如下所示:

GET /foo/bar//baz HTTP/1.1

The pattern would then match as follows:

然后该模式将匹配如下:

0: GET /foo/bar//baz
1: foo/bar/
2: bar/
3: baz

So the requested path /foo/bar//baz would be redirected to /foo/bar/baz (/%1%3).

因此请求的路径/ foo / bar // baz将被重定向到/ foo / bar / baz(/%1%3)。

#1


Apache strips the empty path segment. So /path// is treated as /path/. But your browser doesn’t so relative URLs are resolved using /path//.

Apache剥离空路径段。所以/ path //被视为/ path /。但是您的浏览器不会使用/ path //解析相对URL。

If you want to remove the multiple slashes, you can use the following rule:

如果要删除多个斜杠,可以使用以下规则:

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /(([^/\ ]+/)*)/+([^\ ]*)
RewriteRule ^ /%1%3 [L,R=301]

Explaination

Despite Apache removes empty path segments internal, the THE_REQUEST environment variable (holding the HTTP request line) stays untouched. So we can use this value to check for multiple slashes.

尽管Apache删除了内部的空路径段,但THE_REQUEST环境变量(保持HTTP请求行)保持不变。所以我们可以使用这个值来检查多个斜杠。

  • ^[A-Z]+\ / matches the request method, the following space and the first slash character of the URI path.
  • ^ [A-Z] + \ /匹配请求方法,以下空格和URI路径的第一个斜杠字符。

  • (([^/\ ]+/)*) matches all following non-empty path segments (foo/, foo/bar/, foo/bar/baz/, etc.) or nothing, if there are none.
  • (([^ / \] + /)*)匹配所有后续的非空路径段(foo /,foo / bar /,foo / bar / baz /等),如果没有则匹配。

  • /+ matches the empty path segments as the character before this slash is always another slash (see the expressions before).
  • / +匹配空路径段,因为此斜杠之前的字符始终是另一个斜杠(请参阅前面的表达式)。

  • ([^\ ]*) matches the rest of the URI (that may contain further empty path segments).
  • ([^ \] *)匹配URI的其余部分(可能包含更多空路径段)。

Example: Let’s say we request http://example.com/foo/bar//baz, the request line will look like this:

示例:假设我们要求http://example.com/foo/bar//baz,请求行将如下所示:

GET /foo/bar//baz HTTP/1.1

The pattern would then match as follows:

然后该模式将匹配如下:

0: GET /foo/bar//baz
1: foo/bar/
2: bar/
3: baz

So the requested path /foo/bar//baz would be redirected to /foo/bar/baz (/%1%3).

因此请求的路径/ foo / bar // baz将被重定向到/ foo / bar / baz(/%1%3)。