如何通过.htaccess实现SSL强制、子域名转主域名及404重定向?
.htaccess 配置优化方案
需求整理
需要实现以下4项重定向规则,且全部使用redirect而非rewrite:
- 所有HTTP请求强制跳转到HTTPS;
- www前缀的域名跳转到不带www的主域名;
- 除主域名和www域名外的其他子域名,不管原路径是什么,都302跳转到主域名的
results.php,并把子域名作为q参数,比如http://blog.example.com/post/123→https://example.com/results.php?q=blog; - 主域名下如果请求的文件/目录不存在(即404场景),把URL的首个路径段作为
q参数,跳转到results.php,比如https://example.com/unknown/path→https://example.com/results.php?q=unknown。
当前配置的问题
现有配置存在这些问题:
- 缺少子域名重定向规则,导致该逻辑完全不生效;
- 非SSL转HTTPS的逻辑不完整,仅处理了www域名的非SSL请求,其他域名的HTTP请求未覆盖;
- 规则顺序不合理,容易引发规则冲突,导致部分配置不生效。
现有配置代码:
Options -Indexes RewriteEngine On # this rewrites all non-SSL www to main domain (SSL) RewriteBase / RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] RewriteRule ^(.*)$ https://%1/$1 [R=301,L] #redirect all 404 to query string RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]+)/? /results.php?q=$1 [R=302,L,NC]
修正后的完整配置
将下面的代码替换现有配置,记得把example.com改成你实际的主域名:
Options -Indexes RewriteEngine On RewriteBase / # 1. 强制所有非SSL请求跳转到HTTPS RewriteCond %{HTTPS} off RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] # 2. www域名跳转到不带www的主域名 RewriteCond %{HTTP_HOST} ^www\.(example\.com)$ [NC] RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L] # 3. 其他子域名跳转到主域名,子域名作为查询参数(302,忽略原路径) RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$ [NC] RewriteCond %{HTTP_HOST} ^([a-z0-9-]+)\.example\.com$ [NC] RewriteRule ^ https://example.com/results.php?q=%1 [R=302,L] # 4. 主域名下的404请求重定向,提取首个路径段作为参数 RewriteCond %{HTTP_HOST} ^example\.com$ [NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]+)/? https://example.com/results.php?q=$1 [R=302,L,NC]
关键说明
- 规则顺序不能乱:先处理SSL强制跳转,再处理域名规范化(www转非www),接着处理子域名跳转,最后处理主域名的404。这个顺序能避免规则冲突,比如若先处理子域名跳转,可能会跳过SSL检查;
- SSL跳转全覆盖:通过
%{HTTPS} off判断所有HTTP请求,不管是什么域名,都强制转HTTPS,解决之前非SSL跳转不生效的问题; - 子域名处理精准:先排除主域名和www主域名,再匹配子域名格式,提取子域名部分作为
q参数,直接跳转到指定URL,完全忽略原路径,符合302重定向要求; - 404跳转限定主域名:增加
%{HTTP_HOST} ^example\.com$的判断,确保只有主域名下的404请求才会触发这个规则,不会干扰子域名的跳转逻辑。
内容的提问来源于stack exchange,提问作者Dagon
相关产品推荐
相关产品推荐

