平时使用各种网络传输的时候基本上是以Json
格式进行的, 所以对其他几种格式也是一知半解, 今天静下心对其好好梳理一番.
首先我借鉴了一篇文章(https://segmentfault.com/a/1190000014343759), 和大多数资料一样, 他将类型分为四大类
application/x-www-form-urlencoded,
multipart/form-data,
application/json,
text/xml.
我把他的介绍Copy
了过来, 这几种确实挺常用的, 但是个人而言, 我用的最多的还是json
, 而xml
我几乎只在配置文件有直接接触.
做一个可能不专业的总结, 有错误请指正:
Json
的使用主要是由于REST
的兴起, 而且当下流行前后端分离, 后端使用轻量级的webapi
, 几乎和json
捆绑到一块了.
Xml
的传输场景则是基于SOAP(Simple Object Access Protocol)
, 这个好像接触到的都是Java
开发的.
一、以下是最常用的四种类型:
(1)、application/x-www-form-urlencoded
这应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form>
表单,如果不设置 enctype
属性,那么最终就会以 application/x-www-form-urlencoded
方式提交数据。
<form action="form_action.asp" enctype="text/plain">
<p>First name: <input type="text" name="fname" /></p>
<p>Last name: <input type="text" name="lname" /></p>
<input type="submit" value="Submit" />
</form>
(2)、multipart/form-data
这也是常见的post
请求方式,一般用来上传文件,各大服务器的支持也比较好。所以我们使用表单 上传文件 时,必须让<form>
表单的enctype
属性值为 multipart/form-data
.
(3)、application/json
application/json
作为响应头并不陌生,实际上,现在很多时候也把它作为请求头,用来告诉服务端消息主体是序列化的JSON字符串,除了低版本的IE,基本都支持。除了低版本的IE都支持JSON.stringify()
的方法,服务端也有处理JSON的函数,使用json不会有任何麻烦。
(4)、text/xml
二、个人对传输类型进行的分类
其实这个介绍我认为一点都不具备概括性, 开发的同学肯定都使用过一个叫做Postman的东西
Get
请求都是通过URL进行传参的, 也就是我们途中看到的Params
, 而Post
请求除了可以通过Params
来传参, 最关键的则是Body
, URL携带的参数基本限定在字符串, 并且需要进行URL转码, 而Body
里面则可以有各种格式.
当然none
则是没有Body
, 不作考虑, 拎出来两个特别的:
1、form-data
, 也就是上文中介绍的multipart/form-data
, 他通过一个叫做boundary
的东西来隔绝键值对, 下面是截图:
2、binary
, 这个看名字就能猜出一二, 这个是直接通过二进制流进行传输的, 这个也没啥好解释的.
剩下的, 我都归类到其他类型, 他们有一个共同的特性, Body
内容是一长串字符串, 而在Header
里面会有一个Content-Type
的属性来告诉接收者这个字符串是怎么组织的.
但是这里面还有一个稍微特别一点的, 就是application/x-www-form-urlencoded
, 他需要进行URL转码, 他和Get
请求的URL转码是一个意思.
不同的是, Get请求直接拼接到URL上即可, 而该类型则是放到Body
, 同时加一个Content-Type
的Header
.
三、C#中HttpClient
进行各种类型的传输
我们可以看到, 尽管PostAsync
有四个重载函数, 但是接受的都是HttpContent
, 而查看源码可以看到, HttpContent
是一个抽象类
那我们就不可能直接创建HttpContent
的实例, 而需要去找他的实现类, 经过一番研究, 发现了, 如下四个:
MultipartFormDataContent、FormUrlEncodedContent、StringContent、StreamContent
和上面的总结进行一个对比就能发现端倪:
MultipartFormDataContent
=》multipart/form-data
FormUrlEncodedContent
=》application/x-www-form-urlencoded
StringContent
=》application/json
等
StreamContent
=》binary
而和上面总结的一样FormUrlEncodedContent
只是一个特殊的StringContent
罢了, 唯一不同的就是在mediaType
之前自己手动进行一下URL编码罢了(这一条纯属猜测, 逻辑上应该是没有问题的).