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

本地部署正常;服务器部署 POST 方法参数丢失解决方案

本地部署正常;服务器部署 POST 方法参数丢失解决方案

背景

同一套 JAR 代码,本地127.0.0.1:6060直连测试正常,部署到服务器后通过域名http://web.mycdn66.com调用时,POST 请求 body 中的参数丢失,接口返回{"msg":"无效参数","ok":false}

本文档记录问题原因及解决方案。


问题

问题现象

环境访问方式参数位置结果
本地http://127.0.0.1:6060/...POST body正常
服务器http://web.mycdn66.com/...POST body参数丢失,返回「无效参数」
服务器http://web.mycdn66.com/...?mobile=...URL 查询字符串正常
服务器https://web.mycdn66.com/...POST body正常

问题描述

通过http://访问域名并发送POST请求(参数在 body 中,如multipart/form-data)时,接口返回{"msg":"无效参数","ok":false}

改为https://或把参数放在 URL 查询字符串上则正常。

该问题与后端框架无关(TIO / Spring Boot / JFinal 均可能遇到),根因在Nginx 的 HTTP→HTTPS 跳转HTTP 客户端对 301 的处理方式


复现步骤(失败)

Unirest.post("http://web.mycdn66.com/mytio/sms/beforeCheck.tio_x").multiPartContent().field("p_is_android","1").field("_lau","cn").field("biztype","2").field("mobile","15837827991").asString();

响应:

{"msg":"无效参数","ok":false}

与本项目相关的代码

接口路径:/mytio/sms/beforeCheck.tio_x

控制器:SmsController.beforeCheck

@RequestPath(value="/beforeCheck")publicRespbeforeCheck(Bytebiztype,Stringmobile,HttpRequestrequest)throwsException{returnbizPhoneCheck(biztype,mobile,request);}publicstaticRespbizPhoneCheck(Bytebiztype,Stringmobile,HttpRequestrequest){if(biztype==null||mobile==null){returnResp.fail().msg(RetUtils.INVALID_PARAMETER);// "无效参数"}// ...}

biztypemobilenull时返回"无效参数",说明参数没有到达 Java 应用,而非业务逻辑错误。


根因分析

请求链路对比
访问方式实际路径是否有 301 跳转POST Body
http://web.mycdn66.com/...客户端 → Nginx → 301 → 客户端 → Nginx → Java可能在跳转时丢失
https://web.mycdn66.com/...客户端 → Nginx → Java正常到达
http://127.0.0.1:6060/...客户端 → Java正常到达
301 是什么

301 Moved Permanently表示资源已永久迁移到新地址。Nginx 常见配置:

server { listen 80; server_name web.mycdn66.com; return 301 https://$host$request_uri; }

访问http://时,Nginx不会把请求转发给 Java,而是直接返回 301,告诉客户端去https://再请求一次。

为什么会丢 Body
第 1 次:POST http://域名/xxx body 含 mobile、biztype 第 2 次:Nginx 返回 301 → Location: https://域名/xxx 第 3 次:客户端再 POST https://域名/xxx 很多 HTTP 客户端(Unirest、Apifox、部分 HttpClient)在 301/302 跳转时 不会把原来的 POST body 再发一遍 第 4 次:Java 收到空 body → biztype、mobile 为 null → "无效参数"

注意:

  • Nginx不会主动把参数改成null
  • Java不会因为框架不同而免疫(Spring Boot 同样会遇到)
  • 问题发生在请求到达 Java 之前
为什么 URL 传参不受影响

301 跳转时,新 URL 会保留 query string:

http://域名/xxx?mobile=15837827991&biztype=2 ↓ 301 https://域名/xxx?mobile=15837827991&biztype=2

URL 上的参数会保留,所以即使用http://也能成功。

为什么本地 127.0.0.1 正常

本地直连127.0.0.1:6060,不经过 Nginx,没有 301 跳转,POST body 一次到达 Java。

为什么「同一个 JAR」表现不同

JAR 代码相同,但:

  • 本地测试:127.0.0.1:6060直连
  • 远程测试:web.mycdn66.com经 Nginx,且使用http://

环境链路不同,不是代码不一致。


HTTP 状态码对比

状态码含义POST Body 是否保留(取决于客户端)
301永久跳转很多客户端不保留
302临时跳转很多客户端不保留
307临时跳转,方法不变应保留
308永久跳转,方法不变应保留

常见误解

误解实际情况
JAR 代码和服务器不一致同一 JAR,链路不同(直连 vs 经 Nginx 301)
JFinal 需要先getFile()才能getPara()本项目 HTTP 层是 TIO,不是 JFinal MVC
Nginx 把参数改成了 nullNginx 未转发或客户端跳转时未带 body,Java 读不到参数
Spring Boot 不会有这个问题任何框架都会在 body 未到达时得到 null
只有 multipart 会出问题任何 POST body(JSON、表单、文件)都可能受影响

问题结论

  • 本地正常、服务器异常:不是 JAR 代码不一致,而是请求链路不同(本地直连 vs 服务器经 Nginx)
  • 根因:Nginx 301 跳转 HTTPS,客户端跳转时未保留 POST body
  • 验证:改为https://后问题消失
  • 性质:非 Java 代码问题,属 HTTP 跳转与客户端行为问题

解决方案

方案 1:客户端统一使用 HTTPS(推荐,已验证有效)

将所有http://web.mycdn66.com改为https://web.mycdn66.com

Unirest.post("https://web.mycdn66.com/mytio/sms/beforeCheck.tio_x").header("Cookie","tio_session=...").multiPartContent().field("p_is_android","1").field("_lau","cn").field("biztype","2").field("mobile","15837827991").asString();

注意:

  • 不要手动设置Content-Type: multipart/form-data; boundary=...,交给.multiPartContent()自动生成
  • Apifox、移动端、第三方调用方均需统一改为https://

方案 2:参数放 URL 查询字符串

适用于无文件上传的普通参数接口:

Unirest.post("https://web.mycdn66.com/mytio/sms/beforeCheck.tio_x?p_is_android=1&_lau=cn&biztype=2&mobile=15837827991").header("Cookie","tio_session=...").asString();

无需.multiPartContent()


方案 3:普通表单代替 multipart(无文件时)

Unirest.post("https://web.mycdn66.com/mytio/sms/beforeCheck.tio_x").field("p_is_android","1").field("_lau","cn").field("biztype","2").field("mobile","15837827991").asString();

不调用.multiPartContent(),使用application/x-www-form-urlencoded


方案 4:Nginx 改用 307 跳转(服务端兜底)

将 301 改为 307,要求客户端跳转时保留 POST 方法和 body:

server { listen 80; server_name web.mycdn66.com; return 307 https://$host$request_uri; }

改完后执行:

nginx-tsystemctl reload nginx

方案 5:80 端口 API 直接代理(不跳转)

对 API 路径在 80 端口直接proxy_pass,仅页面对用户做 http→https 跳转:

upstream tio_site_api { server 127.0.0.1:6060; keepalive 32; } server { listen 80; server_name web.mycdn66.com; client_max_body_size 200m; location /mytio/ { proxy_pass http://tio_site_api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1; proxy_set_header Connection ""; } location / { return 301 https://$host$request_uri; } }

注意:HTTP 明文传输安全性较低,生产环境仍建议客户端优先使用 HTTPS。


验证步骤

在服务器上执行:

# 1. 直连 Java(应成功)curl-v-XPOST"http://127.0.0.1:6060/mytio/sms/beforeCheck.tio_x"\-H"Cookie: tio_session=你的session"\-F"p_is_android=1"-F"_lau=cn"-F"biztype=2"-F"mobile=15837827991"# 2. 走域名 HTTP(可能因 301 丢 body 而失败)curl-v-XPOST"http://web.mycdn66.com/mytio/sms/beforeCheck.tio_x"\-H"Cookie: tio_session=你的session"\-F"p_is_android=1"-F"_lau=cn"-F"biztype=2"-F"mobile=15837827991"# 3. 走域名 HTTPS(应成功)curl-v-XPOST"https://web.mycdn66.com/mytio/sms/beforeCheck.tio_x"\-H"Cookie: tio_session=你的session"\-F"p_is_android=1"-F"_lau=cn"-F"biztype=2"-F"mobile=15837827991"

观察第 2 步是否出现301 Moved Permanently,以及第 3 步是否返回{"ok":true}


推荐实践

  1. 所有客户端、Apifox、App 统一使用https://
  2. Nginx 将return 301改为return 307作为兜底
  3. 无文件上传的接口优先用 URL 参数或x-www-form-urlencoded
  4. 不要手动写 multipart 的Content-Typeboundary

相关文件

  • 部署说明:DEPLOY.md(Nginx 配置示例)
  • 接口代码:http-server-api/src/main/java/org/tio/sitexxx/web/server/controller/base/sms/SmsController.java
  • 运行时配置:all/src/main/resources/app-env.propertieshttp.isproxied=true
http://www.jsqmd.com/news/1041589/

相关文章:

  • 平头哥玄铁C910 RTL开发环境实战搭建指南
  • 华为OD机试真题 新系统【数据中心最佳维护窗口】
  • Wand-Enhancer:开源方案实现游戏修改器高级功能完全免费
  • 佳木斯市黄金回收实体店怎么选?这份清单帮你货比三家 - 嵩山路大王
  • 宁波黄金回收2026年排行榜!靠谱回收机构甄选,高价变现黄金攻略 - 名奢变现站
  • 律师执业证丢了登报怎么线上办理?10分钟搞定,次日见报 - 速递信息
  • 2026年6月宁波靠谱的油雾分离器产品推荐,活性炭吸附/催化燃烧RTO/RCO装置/水帘除尘器,油雾分离器加工厂推荐 - 品牌推荐师
  • 2026保山本地连锁黄金回收,承接铂金回收白银银条回收业务+公安备案门店 - 信誉隆金银铂奢回收
  • VisualCppRedist AIO终极指南:一站式解决Windows DLL错误的完整方案
  • 2026台州2026正规漏水检测维修公司精选口碑榜TOP5权威推荐-精准定位检测漏水点-专业防水补漏堵漏维修、卫生间/厨房/屋顶/天沟/地下室/阳台防水漏水检测维修 - 安佳防水
  • 鞍山市闲置黄金变现多少钱?本地5家回收门店最新报价参考 - 马刺总冠军
  • 2026 年高清视频素材 TOP5 平台评测:本土化与国际化资源全面对比
  • 直播操作可视化:如何让观众清晰看到你的每一个精彩操作?
  • 揭阳市2026年黄金回收报价,内行人整理实体门店回收清单 - 嵩山路大王
  • FDE大模型实战指南:小白程序员必备高薪技能,速收藏!
  • OpenCloud云原生改造、服务治理与弹性扩缩容实战
  • 宝鸡市黄金回收去哪儿好?整理了5家靠谱实体店地址电话 - 马刺总冠军
  • AutoUnipus:5分钟搞定U校园网课的智能学习助手
  • 从“修不起”到“修得好”:电驴时代全链条生态如何解题后市场“三不”困局? - 速递信息
  • 2026北京正规二手包包回收怎么选 权威筛选标准+品牌梯队实测指南 - 奢侈品回收测评
  • Windows 11系统瘦身利器:Win11Debloat让电脑重获新生
  • 2026北京二手包包怎么卖最划算 内行计价定级标准与正规渠道梯队盘点 - 奢侈品回收测评
  • 2026广州海珠手表回收实测,逸程二手腕表无克扣压价 - 逸程
  • 2026哈尔滨本地连锁黄金回收,承接铂金回收白银银条回收业务+公安备案门店 - 信誉隆金银铂奢回收
  • 魔兽争霸3必备神器:WarcraftHelper让你的经典游戏焕发新生
  • Three.js 3D模型拆解动画:从基础爆炸到智能散开的进阶实现
  • 5步掌握使用Simscape Electrical设计BLDC电机控制器的核心技能
  • 构建智能数据集成中枢:从ETL到数据价值交付的完整方案
  • Steamless终极指南:如何快速移除Steam游戏的DRM保护?[特殊字符]
  • 消息队列堆积告警:我用 Kafka 消费组重分区把消费延迟从 20 分钟压到 30 秒