htaccess 重写导致副作用

htaccess rewrites causing side affects

我的 .htaccess 文件中有以下内容。

RewriteEngine On
RewriteRule ^([^/]+)?$ /member/profile.php?user= [L]
RewriteRule  ^assets(/.*)?$  /member/assets [L]
RewriteRule  ^images(/.*)?$  /member/images [L]
RewriteRule  ^php(/.*)?$  /member/php [L]

想要的效果是:

https://example.com/username -> https://example.com/member/profile.php?user=

这是有效的,但是,问题是由此产生了 2 个不希望的结果。

首先: https://example.comhttps://example.com/ return 404 错误,但 https://example.com/index.php 工作正常。

其次: https://example.com/username/ 最终转发到 https://example/member/php/?user=username 并 return 出现 404 错误。

我也尝试过

DirectoryIndex index.htm index.html index.php

但这似乎对问题没有影响

我实际想要的最终结果看起来更像:

https://example.com -> https://example.com/index.php
https://example.com/ -> https://example.com/index.php
https://example.com/username -> https://example.com/member/profile.php?user=
https://example.com/username/ -> https://example.com/member/profile.php?user=
RewriteRule ^([^/]+)?$ /member/profile.php?user= [L]

First: https://example.com and https://example.com/ return 404 errors but https://domain.name/index.php works just fine.

第一条规则将捕获请求(因为它允许空 URL-path)并将请求重写为 /member/profile.php?user=。那么,大概是您的脚本触发了 404?

事实上,您似乎在 ? 之前缺少一个斜杠来匹配可选的尾部斜杠(即 /username/username/),而不是制作整个模式选修的! IE。 ^([^/]+)/?$

您还需要 NS (nosubreq) 标志来防止 mod_dir 对 DirectoryIndex(即 index.php)的子请求被这条规则抓住了。然而,这个规则可以说是匹配太多了,因为它也会捕获对 index.php 的直接请求(以及您可能在根目录中拥有的任何其他文件)。因此,也许您需要对 usernames 中允许的字符进行更严格的限制?例如,至少用 ^([^/.]+)/?$? 排除点(以及斜杠)。或者只允许字母和数字(和下划线),例如。 ^(\w+)/?$。 (\w 是一个 shorthand 字符 class,代表 [0-9a-zA-Z_]。)

请注意,第一条规则还将匹配 assetsimagesphp - 因此这些都是有效的用户名。那是故意的吗?您可以反转规则,这样就不会发生这种情况,但您需要确保没有与这些字符串匹配的用户名。

注意:https://example.comhttps://example.com/ 是完全相同的请求。 (浏览器有效地在主机名后附加斜杠以发出有效的 HTTP 请求。请参阅网站管理员堆栈中的以下问题:Is trailing slash automagically added on click of home page URL in browser?

Second: https://example.com/username/ ends up forwarding to https://example.com/member/php/?user=username and returning a 404 error.

我看不出发布的指令会怎样。 None 的规则将匹配 /username/(尾部有斜线),除非 用户名 是“assets”、“images”或“php “——但这仍然不会导致规定的重写?但是,/username/ 会导致 404,因为重写 URL!

实际上没有发生任何事情

您的规则也许应该这样写:

RewriteEngine On
RewriteRule ^(\w+)/?$ member/profile.php?user= [L]
RewriteRule ^assets(/.*) member/assets [L]
RewriteRule ^images(/.*) member/images [L]
RewriteRule ^php(/.*) member/php [L]

规则 2、3 和 4 中的捕获子模式不是可选的,因此我删除了结尾的 ?$

我还删除了替换字符串上的斜杠前缀,使其成为相对字符串 file-path。

也可以进一步“简化”为:

RewriteEngine On
RewriteBase /member
RewriteRule ^(\w+)/?$ profile.php?user= [L]
RewriteRule ^((assets|images|php)/.*)  [L]