Skip to content


nginx强制使用https访问的多种方法(http跳转到https)

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;
        }

}

Posted in Nginx.

Tagged with , , .


No Responses (yet)

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.