如何使用 apache2 mod_rewrite 从文档根目录重定向到文件夹

如何使用 apache2 mod_rewrite 从文档根目录重定向到文件夹

我在 Ubuntu 上安装了 Apache2,为多台主机提供服务。一些主机有网站和 API 部分,还有一些文件夹,这些文件夹uploads应该放在文档根目录之外。我想按照以下文件结构组织它们:

domain
    uploads
    htdocs  //document root
        api
        site

问题是:

  1. 如何在不改变浏览器 uri 的情况下,将除api文档根目录之外的所有请求重定向到文件夹site
  2. 并将浏览器 uri 重写为文档根目录,以便直接向site文件夹发出请求,而不是在浏览器 uri 中/site/..显示/..

我已经尝试了以下方法,但它导致ERR_TOO_MANY_REDIRECTS

RewriteCond %{REQUEST_URI} !^/api/.*$
RewriteCond %{REQUEST_URI} !^/site.*
RewriteRule ^(.*)$ /site/$1 [L]

RewriteCond %{REQUEST_URI} ^/site/?(.*)
RewriteRule .* /%1 [R]

答案1

您遇到了重定向循环,因为重写的 URL 与您要重定向的 URL 匹配。.htaccess重写引擎在第一次重写后重新启动,尽管存在该L标志。该L标志只是停止当前过程,而不会停止所有处理。

  1. 如何在不改变浏览器 uri 的情况下,将除api文档根目录之外的所有请求重定向到文件夹site
  2. 并将浏览器 uri 重写为文档根目录,以便直接向站点文件夹发出请求,而不是在浏览器 uri 中/site/..显示/..

您搞反了术语。#1 实际上是“重写”,而不是“重定向”。您正在内部重写(URL 重写)请求 - 可见的 URL 不会改变。而 #2 是外部“重定向”,而不是“重写”。就像 3xx 外部重定向一样 - 浏览器正在被重定向。

我也会颠倒顺序,所以你先做 #2 - 外部重定向。通常,重定向应该总是在重写之前进行。

请尝试以下操作:

# Redirect direct requests for "/site/<anything>" to "/<anything>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^site/(.*) /$1 [R=302,L]

# Rewrite "/<anything>" to "/site/<anything>"
# except for "/api" and "/site" itself.
RewriteRule !^(api|site)/ /site%{REQUEST_URI} [L]

RewriteCond重定向中的指令会根据环境变量进行检查,从而REDIRECT_STATUS防止出现重定向循环。此变量在初始请求时为空,在第一次成功重写后设置为“200”(即 200 OK 状态)。

第二条规则(重写)使用否定图案排除对/api/site目录的请求。这样就无需单独设置条件。然后我们需要REQUEST_URI代换细绳。

相关内容