有没有办法通过在域的vhost文件中添加规则将https://请求重定向到http://?我正在使用NGINX.
为什么这样的东西有用?乍一看,我不确定是否可以完成.但它提出了一个有趣的问题.
您可以尝试在配置文件中放置重定向语句并重新启动服务器.有两种可能性:
服务器将发出重定向 - 您似乎想要的.
服务器将首先进行https交换,然后发出重定向,在这种情况下,重点是什么?
如果我想出更具体的东西,会增加更多.
更新:( 几小时后) 您可以试试这个.你需要把它放在你的nginx.conf文件中 -
server { listen 443; server_name _ *; rewrite ^(.*) http://$host$1 permanent; }
向客户端发送永久重定向.我假设你使用端口443(默认)为https.
server { listen 80; server_name _ *; ... }
添加此项以便端口80上的正常http请求不受干扰.
更新: 2016
年12月18日 - server_name _
应该使用而不是server_name _ *
nginx版本> 0.6.25(感谢@Luca Steeb)
rewrite
并且if
应该避免使用Nginx.着名的一句是"Nginx不是Apache":换句话说,Nginx有更好的方法来处理URL而不是重写. return
从技术上讲,它仍然是重写模块的一部分,但它并没有带来开销rewrite
,而且并不像它那样需要注意if
.
Nginx已经对整个页面,为什么if
是"邪恶".它还提供了一个建设性的页面,解释了为什么rewrite
和if
不好,以及如何解决它.下面是页面有说关于rewrite
和if
:
这是一种错误,繁琐且无效的方式.
您可以妥善解决这个问题,使用return
:
server { listen 443 ssl; # You will need a wildcard certificate if you want to specify multiple # hostnames here. server_name domain.example www.domain.example; # If you have a certificate that is shared among several servers, you # can move these outside the `server` block. ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/cert.key; # 301 indicates a permanent redirect. If your redirect is # temporary, you can change it to 302 or omit the number # altogether. # $http_host is the hostname and, if applicable, port--unlike $host, # which will break on non-standard ports # $request_uri is the raw URI requested by the client, including any # querystring return 301 http://$http_host$request_uri; }
如果你期望很多机器人不发送Host
标题,你可以使用$host
而不是$http_host
只要你坚持端口80和443.否则,你需要动态填充$http_host
替代品.尽管使用了代码,但只要它出现在server
(而不是location
块中)的根中,该代码就是高效且安全的if
.但是,您需要使用默认服务器才能应用此功能,应使用https避免使用.
set $request_host $server_name:$server_port; if ($http_host) { set $request_host $http_host; }
如果要为特定路径强制执行SSL/TLS,则禁止其他方式:
server { listen 443 ssl; server_name domain.example; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/cert.key; location / { return 301 http://$host$request_uri; } location /secure/ { try_files $uri =404; } } server { listen 80; server_name domain.example; location / { try_files $uri =404; } location /secure/ { return 301 https://$http_host$request_uri; } }
如果您的服务器没有与客户端直接通信 - 例如,如果您正在使用CloudFlare - 事情会变得复杂一些.您需要确保与客户端直接通信的任何服务器X-Forwarded-Proto
都为请求添加了适当的标头.
使用这个是一个混乱的主张; 有关完整说明,请参阅IfIsEvil.为了使其有用,由于各种复杂的原因,if
块不能在location
块内.这会强制使用rewrite
URI测试. 简而言之,如果你必须在生产服务器上使用它...不要.可以这样想:如果你已经超越了Apache,那么你已经超越了这个解决方案.
/ secure,/ secure /,/ secure /中的任何内容都将强制执行https,而所有其他URI将强制执行http.该(?! )
PCRE构造是式断言. (?: )
是一个非捕获组.
server { # If you're using https between servers, you'll need to modify the listen # block and ensure that proper ssl_* statements are either present or # inherited. listen 80; server_name domain.example; if ($http_x_forwarded_proto = https) { rewrite ^(?!/secure)/ http://$http_host$request_uri? permanent; } if ($http_x_forwarded_proto != https) { rewrite ^/secure(?:/|$) https://$http_host$request_uri? permanent; } }
location / { if ($scheme = https) { rewrite ^(.*)? http://$http_host$1 permanent; } }