gpt4 book ai didi

apache - 无法忽略带有 NS 标志的 mod_rewrite 内部重定向

转载 作者:行者123 更新时间:2023-12-01 22:43:39 24 4
gpt4 key购买 nike

我在 .htaccess 文件中定义了几个 mod_rewrite 规则,其中一个规则用于重写 /rwtest/source.html 中的 URL 路径到/rwtest/target.html,另一个禁止直接访问/rwtest/target.html。也就是说,所有希望查看 /rwtest/target.html 内容的用户都必须在其 URL 栏中输入 /rwtest/source.html

我试图在禁止规则中使用 NS 标志来防止重写的 URL 也被拒绝,但该标志似乎无法区分第一个请求和内部重定向。似乎 NS 应该完成这项工作,但我确信我误解了一些东西。

有人可以澄清这种行为吗?到底是什么使得这个内部重定向不是 NS 标志可以忽略的内部子请求?

详细信息:

这是我的完整 .htaccess 文件:

Options +FollowSymLinks -Multiviews

RewriteEngine on
RewriteBase /rwtest

# Forbid rule. Prohibit direct access to target.html. Note the NS flag.
RewriteRule ^target.html$ - [F,NS]

# Rewrite rule. Rewrite source.html to target.html.
RewriteRule ^source.html$ target.html

我在 Windows 7 x64 上运行 Apache 2.4.9,但我在 Linux 上的 Apache 2.4.3 上观察到类似的行为。以下是对 /rwtest/source.html 请求的日志输出。

[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] strip per-dir prefix: C:/Apache24/htdocs/rwtest/source.html -> source.html
[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] applying pattern '^target.html$' to uri 'source.html'
[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] strip per-dir prefix: C:/Apache24/htdocs/rwtest/source.html -> source.html
[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] applying pattern '^source.html$' to uri 'source.html'
[rewrite:trace2] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] rewrite 'source.html' -> 'target.html'
[rewrite:trace3] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] add per-dir prefix: target.html -> C:/Apache24/htdocs/rwtest/target.html
[rewrite:trace2] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] trying to replace prefix C:/Apache24/htdocs/rwtest/ with /rwtest
[rewrite:trace5] [rid#20b6200/initial] strip matching prefix: C:/Apache24/htdocs/rwtest/target.html -> target.html
[rewrite:trace4] [rid#20b6200/initial] add subst prefix: target.html -> /rwtest/target.html
[rewrite:trace1] [rid#20b6200/initial] [perdir C:/Apache24/htdocs/rwtest/] internal redirect with /rwtest/target.html [INTERNAL REDIRECT]
[rewrite:trace3] [rid#20ba360/initial/redir#1] [perdir C:/Apache24/htdocs/rwtest/] strip per-dir prefix: C:/Apache24/htdocs/rwtest/target.html -> target.html
[rewrite:trace3] [rid#20ba360/initial/redir#1] [perdir C:/Apache24/htdocs/rwtest/] applying pattern '^target.html$' to uri 'target.html'
[rewrite:trace2] [rid#20ba360/initial/redir#1] [perdir C:/Apache24/htdocs/rwtest/] forcing responsecode 403 for C:/Apache24/htdocs/rwtest/target.html

解决方法

我发布了一些解决方法 below .

最佳答案

有几种解决方法,每种方法都有其优点和缺点。作为免责声明,我仅在 .htaccess 上下文中测试了它们。

<小时/>

解决方法 1. 检查 REDIRECT_STATUS 是否为空

添加一个 RewriteCond 检查 %{ENV:REDIRECT_STATUS} 是否为空。如果为空,则当前请求不是内部重定向。

优点

  • 确定内部重定向的最直接方法。

缺点

  • 缺乏文档。页面Custom Error Responses简要提到这个变量:

    REDIRECT_ environment variables are created from the environment variables which existed prior to the redirect. They are renamed with a REDIRECT_ prefix, i.e., HTTP_USER_AGENT becomes REDIRECT_HTTP_USER_AGENT. REDIRECT_URL, REDIRECT_STATUS, and REDIRECT_QUERY_STRING are guaranteed to be set, and the other headers will be set only if they existed prior to the error condition.

    我已经尝试了 RewriteCond 中的所有其他 REDIRECT_ 变量,但除了 REDIRECT_STATUS 之外的所有变量对于内部重定向都是空的。为什么 REDIRECT_STATUSmod_rewrite 中的特殊状态仍然是一个谜。

示例

# Forbid rule. Prohibit direct access to target.html.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^target.html$ - [F]

# Rewrite rule. Rewrite source.html to target.html.
RewriteRule ^source.html$ target.html

此方法的来源请参阅 URL rewrite : internal server error .

<小时/>

解决方法 2. 使用 END 停止重写规则处理

L 标志不同,END 会停止重写规则,即使对于内部重定向也是如此。

优点

  • 简单。只是一个额外的标志。

缺点

  • 无法让您充分控制要处理哪些规则以及要跳过哪些规则。

示例

# Forbid rule. Prohibit direct access to target.html.
RewriteRule ^target.html$ - [F]

# Rewrite rule. Rewrite source.html to target.html.
RewriteRule ^source.html$ target.html [END]

有关更多信息,请参阅END flag .

<小时/>

解决方法 3. 与 THE_REQUEST 中的原始网址匹配

%{THE_REQUEST}

The full HTTP request line sent by the browser to the server (e.g., "GET /index.html HTTP/1.1").

THE_REQUEST 不会随内部重定向而改变,因此您可以对其进行匹配。

优点

  • 即使在第二轮网址处理中也可用于匹配原始网址。

缺点

  • 比其他方法复杂得多。强制使用 RewriteCond,其中只需一个 RewriteRule 就足够了。

  • 与大多数其他变量不同,与未转义(解码)的完整 URL 进行匹配。

  • 在多个RewriteRule中使用不方便。可以将 RewriteCond 复制到每个 RewriteRule 之上,或者可以将值导出到环境变量(请参阅示例)。两种老套的选择。

示例

# Forbid rule. Prohibit direct access to target.html.
RewriteCond %{THE_REQUEST} "^[^ ]+ ([^ ?]*)" # extract path from request line
RewriteCond %1 ^/rwtest/target.html$
RewriteRule ^ - [F]

# Rewrite rule. Rewrite source.html to target.html.
RewriteRule ^source.html$ target.html

或者,将路径导出到环境变量并在多个 RewriteRule 中使用它。

# Extract the original URL and save it to ORIG_URL.
RewriteCond %{THE_REQUEST} "^[^ ]+ ([^ ?]*)" # extract path from request line
RewriteRule ^ - [E=ORIG_URL:%1]

# Forbid rule. Prohibit direct access to target.html.
RewriteCond %{ENV:ORIG_URL} ^/rwtest/target.html$
RewriteRule ^ - [F]

# Rewrite rule. Rewrite source.html to target.html.
RewriteCond %{ENV:ORIG_URL} ^/rwtest/source.html$
RewriteRule ^ target.html

关于apache - 无法忽略带有 NS 标志的 mod_rewrite 内部重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24258931/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com