Apache 2.4 转换.htaccess并将其重写为vhost.conf

Apache 2.4 转换.htaccess并将其重写为vhost.conf

我正在重写从旧开发团队收到的 Apache 2.4 配置。

我有大约 200 行类似的配置,我不明白我需要根据什么原理更改此代码才能将其从.htaccess虚拟主机移出。

RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^(.*)$ /$1/ [R,L,NC]

当我将它移动到虚拟主机时,我的网站在我无法理解的地方崩溃了。

答案1

这取决于<VirtualHost>将这些指令放置在容器中的什么位置。

如果您使用<Directory>容器(即目录上下文)和禁用 .htaccess完全覆盖(否则.htaccess将覆盖<Directory>容器!)那么您可以按原样复制指令(假设容器<Directory>引用与文件相同的目录.htaccess)。

但是,如果你将这些指令直接放在容器内部<VirtualHost>(容器外部<Directory>),即在虚拟主机上下文,那么您需要进行一些更改。这是因为在请求映射到文件系统之前,指令会被更早地处理。

在您发布的指令中,仅需要进行两处更改:

  • 在一个虚拟主机上下文中,REQUEST_FILENAME服务器变量尚未解析为文件名REQUEST_URI。它与(即请求的 URL)相同。因此,您的文件系统检查将始终失败,而条件将始终成功!您要么需要使用前瞻。例如%{LA-U:REQUEST_FILENAME},要么自己构建绝对文件名。例如%{DOCUMENT_ROOT}%{REQUEST_URI}。例如:

    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
    
  • 在一个虚拟主机上下文,与RewriteRule 图案是相对于根目录的(以斜杠开头)。而相对于.htaccess包含文件的目录.htaccess- 减去斜杠前缀。因此,规则的书写方式会导致 URL 路径开头出现双斜杠,应改写为:

    RewriteRule ^/(.*)$ /$1/ [R,L]
    

    NC这里不需要标志。)

    或者(最好)不要在这里使用反向引用,而是使用REQUEST_URI服务器变量(这自然也可以工作.htaccess)。例如:

    RewriteRule ^ %{REQUEST_URI}/ [R,L]
    

    在旁边:这可能也应该是 301 永久重定向(即R=301)。目前,这将默认为 302 临时重定向。但只有在您确认它按预期工作后,才更改为 301(如果这是意图)。)

因此,总而言之,这将是:

RewriteCond %{QUERY_STRING} ^$
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^/(.*)$ /$1/ [R,L]

在旁边:

可以通过移动文件系统检查(相对较昂贵的)到最后一个条件并移动状况检查请求是否已以斜线结尾。此外,每个RewriteRule正则表达式子模式(.*)状况不是必需的。因此,上面的代码可以更有效地重写:

RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_URI} !^/application-module/
RewriteCond %{REQUEST_URI} !json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/ [NC]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule !/$ %{REQUEST_URI}/ [R,L]

如果您排除包含(看起来像)文件扩展名的请求,则可以完全删除文件系统检查,但这取决于您的文件结构。

状况检查!json$看起来应该真正检查.json文件扩展名,即。!\.json$(这与我上面关于排除的评论相联系全部具有“文件扩展名”的请求。)

首先状况检查查询字符串是否为空似乎有点奇怪(因为在 URL 路径附加斜杠时是否存在查询字符串并不重要),但我认为这一定是一个特定的要求?

相关内容