如何组合.htaccess重写规则:子目录作根目录并强制HTTPS与非www
.htaccess规则配置问题解答
问题1:是否应将强制HTTPS和非www的规则添加在RewriteEngine On与第一个RewriteCond之间?
是的,必须把强制HTTPS和非www的规则放在所有其他规则最前面(也就是RewriteEngine On之后,原有子目录映射规则之前)。
这类域名和协议的规范化重定向属于基础前置规则,需要先将所有请求统一到https://example.com这个标准地址上,再处理后续的子目录映射逻辑。如果把这类规则放在后面,可能会导致子目录映射后的请求再次被重定向,引发多余的跳转,甚至出现逻辑冲突。
调整后的完整规则示例:
RewriteEngine On # 第一步:强制跳转到非www的HTTPS地址 RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC] RewriteRule ^(.*)$ https://example.com/$1 [R=301,L] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://example.com/$1 [R=301,L] # 第二步:处理子目录作为根目录的映射 RewriteCond %{HTTP_HOST} ^example\.com$ [NC] RewriteCond %{REQUEST_URI} !^/subdirectory/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /subdirectory/$1 [L] RewriteCond %{HTTP_HOST} ^example\.com$ [NC] RewriteRule ^(/)?$ subdirectory/index.html [L]
问题2:每条规则是使用原始请求还是每次规则都会修改原始请求?
mod_rewrite是按顺序逐规则处理请求,且后续规则会基于前序规则修改后的请求内容进行匹配,除非规则带有[L]标记(该标记会终止当前一轮的规则处理,直接返回结果)。
举个实际流程例子:
- 用户发起原始请求
http://www.example.com/test - 经过第一条强制非www的规则后,请求被修改为
https://example.com/test,触发301跳转 - 用户浏览器跳转后发起新请求
https://example.com/test,此时后续的子目录规则会匹配这个更新后的请求URI,将其内部转发到/subdirectory/test
需要注意两个关键变量的区别:
%{REQUEST_URI}、%{REQUEST_FILENAME}这类变量会随规则修改实时更新,存储当前处理阶段的请求信息- 如果需要基于原始请求做判断,要使用
%{THE_REQUEST}变量,它会始终保存用户最初发起的请求内容,不会被后续规则修改
内容的提问来源于stack exchange,提问作者Tokant
相关产品推荐
相关产品推荐

