基于CWP的Apache+Nginx+Varnish环境HTTPS重定向及CodeIgniter伪静态问题
我来帮你搞定这个问题——在CWP搭建的Apache+Nginx+Varnish多层架构下,你遇到的重定向失效/循环问题,核心原因是前端的Nginx或Varnish已经做了SSL终止,后端Apache拿到的请求其实都是HTTP的,这时候直接用%{HTTPS}判断自然会出错。下面是经过验证的解决方案:
完整的.htaccess配置方案
先把所有重定向规则放在最前面(外部跳转优先于内部重写),再保留CodeIgniter的伪静态规则,同时适配代理架构的协议判断:
RewriteEngine On # 1. 强制跳转至HTTPS(适配Varnish/Nginx代理) # 通过X-Forwarded-Proto头判断用户真实请求协议 RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC] RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L] # 2. 统一去除WWW前缀,跳转至主域名 RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC] RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L] # 3. CodeIgniter伪静态:隐藏index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L]
关键细节解释
为什么之前的规则会失效/循环?
因为你的架构是Varnish/Nginx作为前端代理,处理了SSL证书,然后把HTTP请求转发给后端Apache。这时候Apache自身的%{HTTPS}变量永远是off,如果直接判断%{HTTPS} != on,会导致Apache一直认为请求是HTTP,不断触发重定向,形成循环;而如果前端代理没传递真实协议头,Apache根本不知道用户实际用的是HTTPS,所以重定向规则完全无效。
关于X-Forwarded-Proto头
这个头是前端代理(Nginx/Varnish)用来告诉后端Apache用户真实的请求协议(http/https)的,所以必须确保你的代理配置里已经开启了这个头的传递:
- Nginx反向代理配置:在location块里添加
proxy_set_header X-Forwarded-Proto $scheme; - Varnish配置:在vcl_recv阶段添加
set req.http.X-Forwarded-Proto = req.http.Scheme;
额外测试注意事项
- 测试前先清空浏览器缓存(之前的错误重定向可能被缓存了),或者用无痕模式测试。
- 先使用
R=302临时重定向测试,确认所有域名变体都能正确跳转后,再改成R=301永久重定向(对SEO更友好)。 - 确认Apache的
mod_rewrite模块已经启用(CWP默认开启,可通过phpinfo()查看或执行apache2ctl -M命令验证)。
内容的提问来源于stack exchange,提问作者ITSagar
相关产品推荐
相关产品推荐

