Nginx转发post请求变get请求_nginx post-程序员宅基地

技术标签: java  nginx  http  

最近用nginx转发请求,但是明明是post请求,打到服务上确实get请求,body中的参数都没了,于是去查背后详细的原因。

背景

Nginx配置

  • ip及端口:192.20.81.34:8081
  • conf关键配置:
location /select/dosomething/ {
      proxy_pass http://xx.xx.xx.xx:18000/select/dosomething/;
 }

请求连接

http://192.20.81.34:8081/select/dosomething

网上查询处理方法

1.http请求被转发至https请求引起重定向,导致post变get,显然这个和我的情况无关

2.location后连接多了个/,把/去掉就好了,如:解决 nginx 转发POST变成GET - 灰信网(软件开发博客聚合)icon-default.png?t=M276https://www.freesion.com/article/99851192529/

第二个好使!!

问题分析

虽然按照第二个把/去掉后正常了,但是那篇文章中并没有解释为什么会导致这样的现象,于是本着好奇的态度,去查了一下原因,结果如下

一、为什么post会转get?

post转get其实不是Nginx导致的!而是重定向导致的!出现这种情况,你可以在nginx的logs/access.log里面看到有两条记录。

"POST /select/dosomthing HTTP/1.1" 301 185 "-" "PostmanRuntime/7.28.4"
"GET /select/dosomthing/ HTTP/1.1" 500 389 "http://192.20.81.34:8081/select/dosomthing" "PostmanRuntime/7.28.4"

这两条记录可以看出,我是使用postman进行请求,第一条post请求nginx收到了并返回了301HTTP状态码,接着postman就发出了第二条请求,第二条请求就变成了GET请求,且请求最后加了/,变成了

http://192.20.81.34:8081/select/dosomething/

查询301的状态码对应的是永久重定向,正常情况下请求发送方接到301状态码,表示需要重定向,于是会改变请求的url再次请求,但是!有的时候会将请求强行改为get,详情可见:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Redirectionsicon-default.png?t=M276https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Redirections

可以看到 

有些时候处理301状态码时,会把请求方法强行改成get,当然这个问题也被人发现,后面区分出了308状态码,这个状态码不会改变请求方式。

所以是301状态码引起了post请求变成了get请求,而整个流程就较为清晰了:

  1. nginx收到post请求
  2. 返回301状态码,并指定新的访问连接,且该连接就是原连接+/
  3. 发送方收到301状态码,将请求方式改为get,并请求新连接
  4. 服务收到get请求,body参数全部失效

二、为什么会发生重定向?

这个重定向似乎发生的非常隐蔽,似乎是触发了nginx的某种机制,从现象上看,该机制是nginx自动添加末尾斜杠的机制。

我在nginx中配置的连接是

/select/dosomething/

而我实际请求的连接是

/select/dosomething

明显(虽然排查的时候也没看出来)末尾少了一个/,这种情况下nginx会通过301重定向的方式来补全最后/,让发送方重新请求,从而完成匹配。

这个机制也有人提到过,比如:nginx url自动加斜杠问题 - 陈一风 - 博客园一、首先对比说明Nginx以下两个现象: 1. 访问的uri最后带斜杠 http://localhost/product/ >>>> 查找 product下的index页面,存https://www.cnblogs.com/jedi1995/p/11320357.html

但是我并没有在nginx官网中找到官方描述(可能仅仅是因为我没找到)

问题反思

现在整个问题流程就很清晰了

  1. 发送方请求了一个少了最后/的请求
  2. nginx返回301状态码,并返回补全/的重定向连接
  3. 发送方因为301状态码,将请求改为get请求,并按照新连接发送
  4. nginx获得新的连接,完成匹配,并转发
  5. 服务获得get请求

我在想这是不是一个bug?如果nginx返回采用308状态码是不是就能够避免这个问题了?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_29500875/article/details/123688681

智能推荐

【NLP公开数据集】FUNSD dataset 数据集介绍-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏2次。数据集介绍一个可用于FUNSD(噪声很多的扫描文档)上进行表单理解的数据集。这里的表单理解是指对表单中的文本内容进行抽取,并生成结构化数据。数据集包含199个真实的、完全注释的、扫描的表单。文档有很多噪声,而且各种表单的外观差异很大,因此理解表单是一项很有挑战性的任务。该数据集可用于各种任务,包括文本检测、光学字符识别、空间布局分析和实体标记/链接。第一个具有完整注释的公共数据集,可用..._funsd dataset

专题13:一文让你彻底明白python中的进程、线程、协程、GIL_进程/线程/协程区别。python的gil机制了解吗?讲一讲为什么有gil-程序员宅基地

文章浏览阅读279次。文章内容可能会比较长,针对每一部分的内容,建议深入了解,我之所以把这些知识点放在一起解析,\color{red}{文章内容可能会比较长,针对每一部分的内容,建议深入了解,我之所以把这些知识点放在一起解析,}文章内容可能会比较长,针对每一部分的内容,建议深入了解,我之所以把这些知识点放在一起解析,一是想比较清晰的整理出来,遇到问题不用到处找,二是坚持学完python中的这一部分知识,不要只是一知半解。\color{purple}{ 一是想比较清晰的整理出来,遇到问题不用到处找,二是坚持学完python中的这_进程/线程/协程区别。python的gil机制了解吗?讲一讲为什么有gil

AndroidKeyStore管理及实现-基于源码7.1.1.r13_android keystore_cli_v2-程序员宅基地

文章浏览阅读3.4k次。一、 Java层代码实现及调用1. Apps接口调用—证书导入apk(1) 代码路径为:packages/apps/Settings/src/com/android/settings/CredentialStorage.java(2) 功能为UNLOCK/ INSTALL/ RESET通过调用android.security.keystore_android keystore_cli_v2

十个炫丽的表白模板源码,整合成一个完整系统可修改文字,可统计人数,经典的爱情告白,万能告白模板,胜过鲜花表白,程序员的特殊表白方式说——我爱你(520)——html、js、css、jQuery_告白软件页面模版-程序员宅基地

文章浏览阅读3.8k次,点赞13次,收藏34次。十个炫丽的表白模板源码,整合成一个完整系统可修改文字,可统计人数,经典的爱情告白,万能告白模板,胜过鲜花表白,程序员的特殊表白方式说——我爱你(520)——html、js、css、jQuery。一、效果展示点击下方视频,可播放一些效果。 特别的节日给特别的你,万能告白模板,胜过鲜花表白,程序员的特殊表白方式说—..._告白软件页面模版

【C++】STL 标准模板库-程序员宅基地

文章浏览阅读320次,点赞5次,收藏6次。STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

JavaWeb_15_01_Response_java web api responsevo-程序员宅基地

文章浏览阅读156次。1 Response—设置响应信息方法介绍1.1 设置响应行1、格式: HTTP/1.1   200  OK2、设置状态码:void setStatus(int 状态码)1.2 设置响应头void setHeader(String name,Object value)1.3 设置响应体使用步骤:1、获取输出流2、使用输出流,将数据输出到客户端浏览器字符输出流:PrintWriter getWriter()字节输出流:ServletOutputStream getOu_java web api responsevo

随便推点

boot jersey_Jersey和Spring Boot入门-程序员宅基地

文章浏览阅读267次。boot jersey 除了许多新功能,Spring Boot 1.2还带来了Jersey支持。 这是吸引喜欢标准方法的开发人员的重要一步,因为他们现在可以使用JAX-RS规范构建RESTful API,并将其轻松部署到Tomcat或任何其他Spring's Boot支持的容器中。 带有Spring平台的Jersey可以在mico服务的开发中发挥重要作用。 在本文中,我将演示如何使用Sprin..._jersey框架与springboot区别

CTF——PHP审计——变量覆盖_foreach($_get as $key => $value)-程序员宅基地

文章浏览阅读3.9k次,点赞12次,收藏36次。一,变量覆盖漏洞参考:https://www.cnblogs.com/xiaozi/p/7768580.html通常将可以用自定义的参数值替换原有变量值的情况称为变量覆盖漏洞。经常导致变量覆盖漏洞场景有:1,$$使用不当,2,extract()函数使用不当,3,parse_str()函数使用不当,4,import_request_variables()使用不当,5,开启..._foreach($_get as $key => $value)

博客项目(三)——Mapper接口与其映射_piblic interface articlemapper-程序员宅基地

文章浏览阅读717次。一.接口与映射文件未学习MyBatis之前,连接数据库是使用JDBC,执行SQL语句都是使用Statement 和 PreparedStatement这两个对象。在学习了MyBatis之后,学会接口对应映射文件这种方法。1.1Article1.1.1接口package com.test.ssm.blog.mapper;import com.test.ssm.blog.ent..._piblic interface articlemapper

Debezium 从oracle抓取数据到kafka_oracle通过debezuim 同步到kafka confluent-程序员宅基地

文章浏览阅读3.6k次,点赞6次,收藏27次。环境操作系统版本[root@localhost kafka_2.13-2.8.0]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [root@localhost kafka_2.13-2.8.0]# uname -r3.10.0-862.el7.x86_64glibc版本[root@localhost kafka_2.13-2.8.0]# rpm -qa|grep glibcglibc-common-2.17-2_oracle通过debezuim 同步到kafka confluent

Android常用面试题(一)_android面试题 属性动画-程序员宅基地

文章浏览阅读610次。1、 android 中的动画有哪几类,它们的特点和区别是什么? 参考答案: 有两种,一种是 Tween(补间) 动画、还有一种是 Frame(帧) 动画。Tween 动画,这种实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化;另一种 Frame 动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。2.请简述Handler的机制原理_android面试题 属性动画

SAPUI5 (4) - Input组件_sap is_input格式-程序员宅基地

文章浏览阅读938次。学习目标:掌握Input一般组件用法学习内容:1、 Feed Input2、 Input List Item3、 Date Time Input4、 Mask Input5、 Multi Input代码如下:OverView.view.xml// An highlighted block <App> <pages> <Page title="OverView"> <VBox> <Panel he_sap is_input格式

推荐文章

热门文章

相关标签