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.com
和 https://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_]
。)
请注意,第一条规则还将匹配 assets
、images
和 php
- 因此这些都是有效的用户名。那是故意的吗?您可以反转规则,这样就不会发生这种情况,但您需要确保没有与这些字符串匹配的用户名。
注意:https://example.com
和 https://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]
我的 .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.com
和 https://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
andhttps://example.com/
return 404 errors buthttps://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_]
。)
请注意,第一条规则还将匹配 assets
、images
和 php
- 因此这些都是有效的用户名。那是故意的吗?您可以反转规则,这样就不会发生这种情况,但您需要确保没有与这些字符串匹配的用户名。
注意:https://example.com
和 https://example.com/
是完全相同的请求。 (浏览器有效地在主机名后附加斜杠以发出有效的 HTTP 请求。请参阅网站管理员堆栈中的以下问题:Is trailing slash automagically added on click of home page URL in browser?)
Second:
https://example.com/username/
ends up forwarding tohttps://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]