由Http Post提交遇到的一个坑,深入详解4种Post发送数据编码方式
由Http Post提交遇到的一个坑,深入详解4种Post发送数据编码方式
阅读引导:
1、Http post的4中提交方式详解
2、遇到的一个较深的坑,以及解决思路。
最近团队的某个项目遇到一个诡异的问题。
通过生产应用程序调用客户的服务时,报错500.
但是,通过Postman模拟报文发送相同,却返回正确。
难点在于客户的生产程序没有打日志……据了解,客户使用的是C#开发,开发人员已经交接过多次,无法确认程序问题。
不过幸好,这个客户提供的服务通信协议是Http。也就是说,可以通过网络抓包解决。
1
解决路径
由于是客户报错500,而对方又不配合排查,且程序没有打印日志,只能猜测那个地方可能出问题。(苦逼的乙方)
一个大背景是在去年,双方已经在测试环境经过了验证,然后投产了。
但是双方程序员都坚称自己没有改动过程序……
经过一系列的混乱后,制定了解决路径方法。
首先,业务协调客户开发人员加上日志,在晚上配合临时替换生产程序,查出到底是哪里报错。
其次,生产环境抓包,本地互联网环境也抓postman 的发送请求报文,比较异同点。(幸好对方是http)
2
问题原因
由于开发环境管控,开发人员进行postman发送,并安装wireshark抓包,进展缓慢。
幸而,客户方面取得突破。
上线日志打印之后,终于发现问题。
客户程序对于Http请求报文序列化之后,得到的参数有一些是空,但是我方发送报文明明是发送了参数。
然后,客户又在处理Http报文的入口,进来就打印程序,发现所有的参数全部都存在。
因此,怀疑是客户那边自己的程序出了问题。
但是,后来客户坚称没有改动,也不愿因此改动。
比对了一些Http请求报文后,发现入口程序打印的请求参数部分类似这样:&syscode&transcode=12345
客户开发人员称:对方是C#的处理框架,对于参数为空的方式,也必须送“=”,也就是说,上面部分的内容应该是:&syscode**=**&transcode=XR10010
作为乙方,只好再次去适配客户解决。在发送Http post请求的时候,对所有的参数做了判空处理,空值参数不再发送给客户。
3
HttpClient对于此方式的处理
在解决了生产问题之后,反过来去研究对于Http请求,到底是怎么回事。
应用程序调用的是HttpClient4.5.3 发现,底层对于:content type是application/x-www-form-urlencoded的编码提交方式,有处理判断。
如果是空值,则不拼接“=”。
主要是:URLEncodeUtils.java
其中主要逻辑代码如下,其中:NAME_VALUE_SEPARATOR 就是 “=”
if(encodedValue!=null){
result.append(NAME_VALUE_SEPARATOR);
result.append(encodedValue);
}
4
HTTP的四种Post提交编码发送方式
HTTP协议规范把HTTP的请求分为三部分:状态行、请求头、消息主体。
应用开发提交的数据,一般需要放在消息主体(entity-body)中(对于请求头中的内容,一般不做变更,但是有一些开发规范会要求在请求头中放签名字段),但是对于entity-body中的内容具体用什么编码方式,协议并没有规定。
所以,需要在Http的请求头中,指定编码方式,使得客户端与服务器端进行协商。
对于Post请求来说,编码方式一般分为四种:
application/x-www-form-urlencoded
这是最常见的编码方式,首先,Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。 大部分服务端语言都对这种方式有很好的支持。
按照HTTP的报文协议规范,发送的请求长成这个样子:
POST http://www.test.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3`
multipart/form-data
我们使用表单上传文件时,必须让 表单的enctype 等于 multipart/form-data
application/json
这种情况想,发送上面的同样的请求,http报文为:
POST http://www.test.com HTTP/1.1
Content-Type: application/json;charset=utf-8{"title":"test","sub":[1,2,3]}
text/xml
POST http://www.example.com HTTP/1.1
Content-Type: text/xml<?xml version="1.0"?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4>41</i4></value>
</param>
</params>
</methodCall>
5
实际应用开发
已经知道了POST提交的四种方式,那么实际应用中该怎么使用呢?
当前,用的比较多的是:application/x-www-form-urlencoded 和 application/json
只不过,在实际开发中,请求中的报文肯定都是密文的,甚至可能都同时传递签名串。
那么,对于application/x-www-form-urlencoded,其报文可能是这样:
POST http://www.test.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
signstr=5est&body=8iejkuopui`
对于application/json
其报文可能是这样:
POST http://www.test.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{“signstr”:“5est”,“body”:“8iejkuopui”}
服务端的web服务器对Http报文体,根据content-type解析后,再传递给应用。
应用程序就可以再去解析响应字段,做解密验签等操作了。
6
Http编码传输
刚才说了,content-type属性,指的是报文体的报文协议编码方式。
那么,我们知道报文是以字节的方式进行网络传输的,整个Http的请求,有没有编码呢?
答案是肯定的。
Http自带的内容还是比较多的,在报文较小的情况下,尤为明显。
这也是Http规范向Http2、3演进的原因。
也是分布式微服务架构,大多使用RPC方式的一个原因点。
为了提升传输速度,减小带宽占用,肯定要对http报文进行编码压缩。
内容编码有如下几种,一般是在请求头上加上:Accept-Encoding;在响应头中加上 Content-Encoding;
gzip(GNU zip)
compress(UNIX系统的标准压缩)
deflate(zlib)
identity(不进行编码)
由Http Post提交遇到的一个坑,深入详解4种Post发送数据编码方式相关推荐
- python避坑_Django搭建项目实战与避坑细节详解
Django 开发项目是很快的,有多快?看完本篇文章,你就知道了. 安装 Django 前提条件:已安装 Python. Django 使用 pip 命令直接就可以安装: pip install dj ...
- 超级棒的一个DP问题详解(入门)
超级棒的一个DP问题详解(入门) 只要耐心看肯定可以理解的~动态规划问题故事描述~ 通过金矿模型介绍动态规划 附上原文地址: http://www.cnblogs.com/sdjl/articles/ ...
- python编写一个名片_详解Python做一个名片管理系统
名片管理系统有两个模块组成:cards_main.py和 cards_tools.py一个是主程序,另一个是封装增删改查函数的被调用程序 代码如下 cards_main.py #! /usr/bin/ ...
- Java基础【之】输出一个菱形(详解)
Java基础[之]输出一个菱形(详解) 代码示例 <目录:Java渐进式学习> <目录:Java设计模式> <目录:从零手写Tomcat> 代码示例 public ...
- Java程序员从笨鸟到菜鸟之(五十一)细谈Hibernate(二)开发第一个hibernate基本详解...
在上篇博客中,我们介绍了<hibernate基本概念和体系结构>,也对hibernate框架有了一个初步的了解,本文我将向大家简单介绍Hibernate的核心API调用库,并讲解一下它的基 ...
- Git(7)-- 查看提交历史(git log 命令详解)
文章目录 1.`git clone` 2.`git log` 3.`git log -p` 4.`git log --stat` 5.`git log --pretty=oneline` 6.`git ...
- 【git 整理提交】git rebase -i 命令详解
git rebase -i 详解 官方文档 变基时可用的命令 变基时有六个命令可用: pick pick只是意味着包括提交.重新进行命令时,重新安排pick命令的顺序会更改提交的顺序.如果选择不包括提 ...
- Dragger 2遇到的坑 Dragger2详解 Dragger2学习最好的资料
我是曹新雨,我为自己代言.现在的菜鸟,3年以后我就是大神.为自己加油.微信:aycaoxinyu Dragger2是什么,我就不再说了.资料一堆,而且里面的注解什么意思,我推荐两篇文章,这两篇都是我精 ...
- Linux中搭建一个ftp服务器详解
来源:Linux社区 作者:luzhi1024 详解Linux中搭建一个ftp服务器. ftp工作是会启动两个通道: 控制通道 , 数据通道 在ftp协议中,控制连接均是由客户端发起的,而数据连接有 ...
最新文章
- Java 详解 JVM 工作原理和流程
- idea常用的快捷键
- 7-5 排列的字典序问题 (10 分)(思路加详解全排列问题+vector容器做法)Come Baby!
- c语言 函数的参数传递示例_restder()函数,带有C ++中的示例
- Spring AOP 的切点切在Controller上没有起作用的问题。
- 疑似禁令影响开始显现:华为Mate 40量产或被迫推迟
- 2016.08.30~2017.07.20
- C#参考:Linq 概述
- (2022.9)raspberry 4安装HP 1020 plus打印机,利用树莓派4制作无线打印服务器
- 关于WES7的系统还原与恢复
- 几个可以免费下载视频素材的网站[国外],希望大家喜欢[可以的话给个关注哟]
- Spring包含JAR的详解
- 【NOTE】python3.6下scons运行提示找不到SCons.Script解决方式
- 第六章(项目进度管理)知识点
- 弹出表情气泡仿魔兽的技能冷效果却实现
- C++打造植物大战僵尸辅助!附完整项目源码
- 05【React再造之旅】从零实现一个React(下)
- 软件产品案例分析——福州大学微信小程序
- python opencv如何读取透明png图片以及如何编辑透明度
- C#桌面程序设计复习
热门文章
- sqlserver:使用 SqlBulkCopy 批量插入数据
- 使用卡尔曼滤波实现单目标跟踪过程中的目标运动轨迹预测
- 平台活动免费送,免费领取1个月优酷/爱奇艺/腾讯视频会员
- oracle数据库中nvarchar,Oracle数据库中的varchar,varchar2,nvarchar,nvarchar2区别及用
- 如何在一个APP内检测手机内安装了另外一个APP并且跳转到另外一个APP内?
- xtrabackup参数详解
- HTML5 Canvas标签
- linux一键安装php环境
- 资本寒冬来临,美图的增长引擎如何发动?
- Java在OJ平台提交的方式与基本套路