当前位置: 首页 > news >正文

[Nginx] 3.由HTTP转发引出的重定向问题

问题背景

最近在调试接口时遇到了一个奇怪的问题:在 Postman 进行调试的时候,使用 HTTPS 协议 POST 请求一切正常,但切换到 HTTP 协议后却报错,并且,错误信息显示请求方法变成了GET,而后端日志显示所有参数的非空校验都失败。

经过一些分析以及排查,排除了代码本身的问题,将问题定位到了 Nginx 转发上。
考虑到安全性,会强制将所有的 HTTP 请求转为 HTTPS,配置如下:

server {listen 80;server_name nginx localhost 127.0.0.1;rewrite ^(.*)$ https://$host$1 permanent;
}

HTTP重定向的工作流程

  • 步骤一:由客户端发送 HTTP POST请求
POST http://api.example.com/login
Body: {"username":"admin","password":"123456"}
  • 步骤二:Nginx 检测到 HTTP,返回301重定向响应
HTTP/1.1 301 Moved Permanently
Location: https://api.example.com/login
  • 步骤三:客户端自动发起新的GET请求
GET https://api.example.com/login
  • 步骤四:服务器收到GET请求
    • 期待POST方法,但收到GET
    • 请求体为空 → 所有参数为null

在第三步中,客户端自动将请求方法从 POST 改成了 GET。这里是涉及到了一个历史中的默认行为。HTTP/1.0规范中对301/302重定向的处理描述比较模糊,但大家约定俗成:301-资源永久移动,302-临时处于不同位置。因此,在浏览器以及 HTTP 客户端在实现时,出于简化考虑,决定对于301/302响应,自动将重定向请求的方法改为GET。
这么做的原因也是考虑到安全性,因为,一般GET方法偏向于请求数据,相比于POST的提交表单等操作,相对而言更加安全,以及幂等性。
对于这个问题,在1.1中引入了 307 和 308 两个新的状态码,可以保留原方法以及请求体。

深入理解:Redirect vs Rewrite

上面的内容实际上已经将问题说的比较清楚了,但要彻底理解这个问题,还需要区分两个概念:

  • Redirect:重定向
    • 服务器告诉客户端"请换个地址重新请求"
    • 客户端感知,地址栏变化
  • Rewrite:重写
    • 服务器内部修改请求路径,客户端无感知
    • 完全在服务器内部完成
    • 例如:rewrite ^/api/(.*)$ /internal/$1 break;

参数处理的差异

URL查询参数(?key=value)

会被保留,因为 Nginx 能够自动追加查询字符串

原始请求:http://api.com/login?token=abc
重定向后:https://api.com/login?token=abc
请求体参数(Body数据)

浏览器/客户端会丢弃原始POST的body数据,同时,转化为 GET 方法,导致完全丢失。

解决方法

方法一:避免HTTP请求

直接使用HTTPS协议,从根本上避免重定向

方法二:使用307/308重定向

保留原始请求方法和请求体

server {listen 80;server_name api.example.com;# 使用307临时重定向,保留POST方法和bodyreturn 307 https://api.example.com$request_uri;
}
方法三:避免重定向

Nginx 同时监听 80 和 443 端口,避免重定向。

方法四:使用重写而不是重定向
# 重写配置
location /submit/ {rewrite ^/submit/(.*)$ /backend/handle/$1 break;proxy_pass http://backend_server;
}
http://www.dtcms.com/a/541054.html

相关文章:

  • 子网站如何做哪个网站有做兼职的
  • hive的SQL语句练习2
  • 做中学网站做课件的网站有哪些
  • 【Java +AI |基础篇day6、7、8 OOP高级 继承 多态 抽象 代码块 内部类 函数式编程】
  • 菲林式投影灯成像模糊?OAS 软件精准优化破瓶颈
  • 匹配最接近的行政区域sql 反向匹配
  • ROS2系列 (6) : 多功能包工作空间(Workspace)最佳实践
  • Nacos动态刷新实战:客户端集成与案例验证
  • 谷歌网站怎么做排名pc端手机网站 viewport 自适应
  • 建设银行衡阳市分行网站数字营销
  • 淄博网站建设卓迅科技有限公司属于什么企业类型
  • 梅州企业网站wap网站推荐
  • 14、Docker swarm-1-理论
  • Jenkins Share Library教程 —— 企业级 Jenkins Shared Library 实战示例
  • 做微新闻怎么发视频网站seo网站沙盒期
  • 中国建设信息港网站wordpress开源程序建站教程
  • Win11 跨设备同步的便笺内容突然丢失,如何恢复?
  • 三、cmake语法-提高篇
  • 仓颉编程(20)泛型
  • Go语言2D游戏开发入门004:零基础打造射击游戏《太空大战》3
  • 学习FreeRTOS(FreeRTOS移植到STM32F103C8T6)
  • json缩放 json 缩放
  • maxkb部署,版本升级步骤与注意事项(超详细图文)
  • 测试开发话题02---概念篇
  • 网站建设推广优化排名全国工商核名查询系统官网
  • ASP Content Linking
  • 【研究生随笔】Pytorch中的卷积神经网络(1)
  • Android运行项目报错集合
  • 为什么电脑会蓝屏?怎么快速解决电脑蓝屏问题
  • js建设网站html5网站开发价格