当前位置: 首页 > 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.gsyq.cn/news/1553497.html

相关文章:

  • 宁波黄金回收2026年排行榜!靠谱回收机构甄选,高价变现黄金攻略 - 名奢变现站
  • Wand-Enhancer:开源方案实现游戏修改器高级功能完全免费
  • 2026 年高清视频素材 TOP5 平台评测:本土化与国际化资源全面对比
  • 2026保山本地连锁黄金回收,承接铂金回收白银银条回收业务+公安备案门店 - 信誉隆金银铂奢回收
  • 揭阳市2026年黄金回收报价,内行人整理实体门店回收清单 - 嵩山路大王
  • 宝鸡市黄金回收去哪儿好?整理了5家靠谱实体店地址电话 - 马刺总冠军
  • 2026北京二手包包怎么卖最划算 内行计价定级标准与正规渠道梯队盘点 - 奢侈品回收测评
  • Windows 11系统瘦身利器:Win11Debloat让电脑重获新生
  • Three.js 3D模型拆解动画:从基础爆炸到智能散开的进阶实现
  • 技术解析:OctFormer如何通过八叉树注意力革新3D点云处理
  • ChatGPT Plus深度解析:上下文、模型调度与文件解析的技术真相
  • 2026年6月城市管网电磁流量计厂家排行榜:国产力量深度洗牌,细分场景下的品牌竞争力全景解析 - 水质仪表品牌排行榜
  • 从平面到立体:Adobe Dimension如何成为PS/AI设计师的3D捷径
  • 2026东莞黄金回收门店,哪家价更高回款更稳测评 - 名奢变现站
  • 2019年CSP-X复赛真题及题解(T1:随机数)
  • 2026年天津黄金回收避坑指南:不迷信连锁看本地口碑 - 讯息早知道
  • 超强的资源搜索神器,附带去水印高清下载功能!
  • 3分钟快速上手BepInEx:让Unity游戏模组开发变得简单
  • WarcraftHelper魔兽辅助工具:终极指南让经典魔兽争霸3焕发新生
  • 2026佛山黄金回收测评!横向对比5家靠谱门店,老手推荐 - 奢侈品回收测评
  • 如何用163MusicLyrics彻底解决音乐歌词管理难题:一个开源工具的完整指南
  • 2026年度学术服务机构综合实力排行榜TOP5:客观测评与选型指南 - 艾德思Editsprings
  • 3个关键策略:用Obsidian日历插件构建可视化知识时间轴
  • Docker 容器引擎安装与基本配置
  • 武汉科谷技工学校2026年电子商务专业招生简章|初中毕业学电商有没有用|技能高考升学班 - 武汉中职最新信息发布
  • 崇左市黄金回收实体店怎么选?这份清单帮你货比三家 - 奢金汇
  • 阿坝藏族羌族自治州黄金回收猫腻多怎么办?整理了5家诚信回收店供参考 - 奢金阁
  • 咸宁市奢侈品手表包包回收价格差距高达15%:实测对比告诉你哪家店报价最实在 - 谊识预商贸
  • Word交叉引用进阶:一键生成规范参考文献列表与智能分隔
  • AI Agent开发面试高频题曝光!从203篇面经提炼,助你拿下Offer!