Nginx POST转GET问题分析

Nginx post转get问题分析

一、问题分析

现网配置:80端口判断不是https,则对url进行rewrite,跳转至443端口(永久重定向)。

server {
        listen *:80 ; 
        server_name xxx.com; 

        if ($scheme != https ) { 
                rewrite ^(.*)$ https://${server_name}$1 permanent; 
        }
}

问题就在于:使用rewrite后,如果替换字符串以" http://"、" https://“或” $scheme"开头,则处理停止并将重定向返回给客户端(官方说法)。
重定向会生成新的子请求,无论原来是不是GET请求,新的重定向请求类型都是GET,请求体也会丢了,所以重定向请求会返回5xx,原请求返回301。

二、结论:

结合官方指令说明并测试:
①rewrite后的URL如果以" http://"、" https://“或” $scheme"开头,则默认生成子请求进行临时重定向302,生成重定向请求是GET类型。
②rewrite 指令结合redirect、permanent结尾使用,无论rewrite 后是不是以" http://"、" https://“或” $scheme"开头,都是重定向,生成子请求是GET类型。

三、解决方案:

(1)不使用rewrite,而使用location、proxy_pass,在nginx内部代理到443端口。

server {
   listen 80;
      location  / {
          if ($scheme != https ) {
          proxy_pass https://10.19.1.82;
          }
      }
}

(2)使用rewrite,但不以" http://"、" https://“或” $scheme"开头,指令不结合redirect、permanent结尾使用,结合location、proxy_pass内部代理(这里只使用location,不用rewrite也可以得到同样的效果,可以理解rewrite为一种更灵活的location,因为都可以对URL进行处理、匹配、代理)。

server {
   listen 80;
         location  /test {
           rewrite  ^/test/(.*)$ /$1  last;
        }

        location  / {
            if ($scheme != https ) {
            proxy_pass https://10.19.1.82;
            }
        }
}

(3)使用return指令,因为return可以指定307状态码来重定向,状态码 307 与 302 之间的区别在于,当发送重定向请求的时候,307 状态码可以确保请求方法和消息主体不会发生变化。对于 GET 请求来说,两种情况没有区别。

server {
   listen 80;
        if ($scheme != https ) { 
           return 307 https://10.19.1.82$request_uri;
        }
}

参考链接:rewrite模块
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值