nginx强制使用https访问的多种方法(http跳转到https)
先说明一下HTTP跳转的状态码
301 Moved Permanently:该方式将所有的 HTTP 请求重定向到 HTTPS 上,并且该重定向是永久性的。客户端在收到 301 响应后,会自动将 HTTP 请求转为 GET 请求,同时将请求地址修改为重定向后的地址。这意味着,如果原始请求是 POST 请求,那么 301 重定向会将其转变为 GET 请求。此外,浏览器会缓存 301 响应,下一次请求时会直接跳转到 HTTPS 上。
302 Found / 303 See Other:这两种方式将所有的 HTTP 请求临时性地重定向到 HTTPS 上。302 Found 的响应会将请求方法保持不变,同时将请求地址修改为重定向后的地址。而 303 See Other 则会将所有请求方法转变为 GET 方法,并将请求地址修改为重定向后的地址。这两种方式都不会缓存响应,下一次请求时会再次发起请求。
307 Temporary Redirect:该方式将所有的 HTTP 请求临时性地重定向到 HTTPS 上,并且会保留原始的请求方法。这意味着,如果原始请求是 POST 请求,那么重定向后的请求仍然是 POST 请求。同时,请求地址也会被修改为重定向后的地址。与 302 Found 类似,307 Temporary Redirect 不会缓存响应,下一次请求时会再次发起请求。
308 Permanent Redirect:该方式将所有的 HTTP 请求重定向到 HTTPS 上,并且该重定向是永久性的。客户端在收到 308 响应后,会自动将 HTTP 请求转为与原始请求方法相同的请求方法,同时将请求地址修改为重定向后的地址。与 301 Moved Permanently 不同的是,308 Permanent Redirect 不会允许浏览器将 POST 请求重定向到新地址。308 响应也会被缓存,下一次请求时会直接跳转到 HTTPS 上。
497 normal request was sent to HTTPS:(HTTP到HTTPS(Nginx))Nginx内置的代码,被用于原始的HTTP的请求发送给HTTPS端口去分辨4XX在日志中和一个错误页面的重定向
推荐使用return 307 跳转码,百度、亚马逊等也是使用307跳转。
方式一:
返回 301 错误,并跳转到 https 地址
server{
listen 80;
listen 443 ssl;
server_name blog.c1gstudio.com;
set $sslflag 0;
if ($ssl_protocol = '') {
set $sslflag "${sslflag}1";
}
if ($sslflag = "01") {
return 301 https://$server_name$request_uri;
}
}
方式二:
当 nginx 配置的站点只允许 https 访问时,我们却使用 http 去访问,此时 nginx 会报出 497 错误码。
我们就可以利用 error_page 命令将 497 状态码的链接重定向到 https
server{
listen 80;
listen 443 ssl;
server_name blog.c1gstudio.com;
error_page 497 https://$server_name$request_uri;
}
方式三:
使用参数标记,只跳转一次https。
将 http 请求重写到 https 地址,并带上?https=Y参数.
PURGE方式不进行跳转
server{
listen 80;
listen 443 ssl;
server_name blog.c1gstudio.com;
set $sslflag 0;
if ($server_port = 80) {
set $sslflag "${sslflag}1";
}
if ( $request_method = "PURGE") {
set $sslflag "${sslflag}2";
}
if ($arg_sslsign ) {
set $sslflag "${sslflag}4";
}
set $ssljumpparam "?https=Y";
if ($is_args = '?'){
set $ssljumpparam "&https=Y";
}
if ($sslflag = "01") {
rewrite ^(.*)$ https://$host$uri$is_args$query_string$ssljumpparam? redirect;
}
}
方式四:
当post数据到http协议时,重定向后会出现请求方法变为 get,post数据丢失。
解决这个问题就要换返回的状态码,307是临时,308是永久.
server{
listen 80;
listen 443 ssl;
server_name blog.c1gstudio.com;
set $sslflag 0;
if ($scheme = http) {
set $sslflag "${sslflag}1";
}
if ($request_method = POST) {
set $sslflag "${sslflag}2";
}
if ($sslflag = "012") {
return 307 https://$host$request_uri;
}
if ($sslflag = "01") {
return 301 https://$host$request_uri;
}
}
方式五:
所有http 的GET请求301跳转至https,
POST等请求的用proxy_pass来接收并反代https
server{
listen 80;
server_name blog.c1gstudio.com;
set $sslflag 0;
if ($ssl_protocol = '') {
set $sslflag "${sslflag}1";
}
if ( $request_method = "GET") {
set $sslflag "${sslflag}2";
}
if ($sslflag = "012") {
return 301 https://$server_name$request_uri;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Pass my_proxy;
proxy_pass https://127.0.0.1;
}
}
No Responses (yet)
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.