Nginx rewrite模块踩坑小计----配置不正确将url重写
前言
今天遇到了一个比较有意思的涉及 nginx 的小问题,这里在测试环境模拟记录一下;
问题现象
客户端访问7层 规则,request url 类似为:http://www.test.com/test?xxx=aaa ; 请求需要重定向到HTTPS ,实际重定向后的请求变成了 https://www.test.com/?xxx=aaa ;url 中的path 丢失了,导致后面业务逻辑报错;
报错现象如下图:
问题分析与处理
业务这里配置重定向的预期是将http 请求 重定向到 https ,保证业务请求的安全性;即正常经过重定向请求的url 应该是 https://www.test.com/test?xxx=aaa ; 但是这里的path 在转发过程中丢失了;
检查nginx 配置文件中,rewrite 相关类似配置如下:
location /test {
rewrite ^/(.*) http://www.testnginx.com:9090/ permanent;
}
发现这里是将所有匹配location 为 /test 的path ,都直接重定向到‘/’ ;导致请求中所带的path 被完全丢弃;
如果需要带原来的url 的正确配置应该如下:
location /test {
rewrite ^/(.*)$ http://www.testnginx.com:9090/$1 permanent;
}
可见,正则后面的目的地址,需要配置变量,将原来的url 统一替换;这样请求就不会出现类似的问题了;
修改后,访问效果见下图:
相关知识记录
这个小问题中涉及到几个知识点简单记录一下;
curl 命令 -v 选项,显示详细请求信息,很常用,可以看出具体请求域名对应的ip和port,以及是否tcp 握手成功,是否已经发出http 请求,以及http 请求类型等;
curl 命令 -L 选项,遇到重定向的请求,继续将重定向的后的url 进行请求,如果不加-L 的话,遇到重定向的请求,就只会看到 301/302 的重定向状态码;
rewrite是 ngx_ http_ rewrite_ module模块下的指令,使用频率非常高。
rewrite支持的配置环境有 server、 location、 if,它通过 break和 last来完成内部重定向功能。内部重定向是在 Nginx内部发送请求的操作,它可以将请求转发到其他的 location或对 URL进行修改,而不必通过 HTTP连接请求,整个操作非常高效。
永久重定向和临时重定向的区分是为爬取搜索引擎而设置的。如果状态码是 301,表示网页地址永久改变,搜索引擎会将旧页面的地址替换成新页面的地址,用户在搜索引擎搜索网站时,就不会再去旧地址了。
如果状态码是 302,表示临时重定向,搜索引擎会保留旧页面的地址,因为它认为跳转只是暂时的。当用户使用搜索引擎搜索网站时,会首先进入旧地址然后再被跳转到 302指定的新地址。
301和 302的跳转并不适合用于 POST请求,如果 POST请求被跳转的话,会先被转化为 GET请求,且请求体的内容会丢失,为此 HTTP 1. 1提供了新的跳转状态码 307和 308。
状态码 307的意义和 302一样,都是临时重定向;而 308和 301一样,都是永久重定向。但如果要求在跳转过程中保持客户端的请求方法不变,需要使用 return指令