按照传输过程,HTTP 报文分为请求报文和响应报文。请求报文和响应报文的结构差不多,这里只对 HTTP 请求报文做一个总结。
HTTP 请求报文由 请求行请求头请求体(请求数据)、空行 四个部分组成(空行不知道算不算报文的一部分)。

一、请求行

  请求行有三个组成部分:请求方法、请求 URL、HTTP 协议版本组成。这三个部分占据一行,每个部分之间用空格隔开。

  在HTTP1.0版本中定义了三种请求方法: GET, POST 和 HEAD 方法

  之后HTTP1.1版本新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

  REST设计风格对应的四种请求类型 GET(获取数据)、POST(添加数据)、PUT(更新数据)、DELETE(删除数据) 就在这八种之内

1.GET: 请求指定的页面信息,并返回实体主体。
2.HEAD: 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
3.POST: 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
4.PUT: 从客户端向服务器传送的数据取代指定的资源。
5.DELETE: 请求服务器删除指定的资源。
6.CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
7.OPTIONS: 允许客户端查看服务器的性能。
8.TRACE: 回显服务器收到的请求,主要用于测试或诊断。

  GET 和 POST 的区别在于 GET 请求数据存储在请求行中,而 POST 请求数据存储在请求体(BODY) 中

  

二、请求头

  请求头部通知服务器有关于客户端请求的信息,由关键字/值对组成,每行一对。

 ----------请求头几种常见可选项----------
Host: 原始的 URL 中的主机和端口
Referer: 所指向的 Web 页的 URL
Accept: 客户端可以处理的 MIME 类型
Accept-Language: 客户端的首选语言(en、en-us等)
Accept-Encoding: 客户端处理的编码类型(gzip、compress等)
User-Agent: 客户端自身信息
Content-Type: POST 数据的 MIME 类型
Content-Length: POST 数据的大小(KB)
Connection:Keep-Alive

 

三、请求体

  POST 方法中发送到服务的表单数据或文件,是一个键值对组合。这个与请求头中 Content-Type 和 Content-Length 密切相关。

  1、不同的提交方式,对应支持的编码类型也不一样

    HTTP协议规定 POST 提交的数据必须放在消息主体,但协议并没有规定数据必须使用什么编码。如我们常见的 form 表单提交方式和 Ajax(jQuery)提交方式

      Ⅰ:form 表单提交,由 enctype 属性值决定编码类型,enctype 属性值支持三种: application/x-www-form-urlencoded、multipart/form-data、text/plain。

      Ⅱ:Ajax(jQuery)通过 contentType 属性设定编码类型,contentType 属性支持:application/x-www-form-urlencoded、multipart/form-data、text/plain、text/xml、application/json。

  2、常见的几种编码类型介绍

    2.1、application/x-www-form-urlencoded(默认值)

      所有字符都会进行编码(多个键值对之间用 "&" 连接,空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值)。

  Content-Type: application/x-www-form-urlencoded;charset=utf-8
username=admin&password=admin

    2.2、multipart/form-data

      该类型用于高效传输文件、非ASCII数据和二进制数据,用指定的分隔符 --boundary 将表单数据逐项分隔。每项数据由几个部分组成:      

      Ⅰ、内容描述信息:Content-Disposition、键名等
        例如:Content-Disposition:form-data;name="username"
        例如:Content-Disposition:form-data;name="admin";filename="admin.jpg"
      Ⅱ、内容类型(可选):Content-Type,默认值为 text/plain。
      Ⅲ、回车(一个空行):用来分隔数据具体的值和其他信息。
      Ⅳ、字段具体内容(文本或二进制)。

  Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

  Content-Disposition:form-data;name="username"
Content-Type:text/plain(
(这里为空行,表示后面是数据)
admin(这里是Value的值)
--WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition:form-data;name="admin";filename="admin.jpg"(这后面必须换行)
Content-Type:image/jpeg(这后面必须换行) ...二进制..--
--WebKitFormBoundaryrGKCBY7qhFd3TrwA--

  3、text/plain

      按照键值对排列表单数据key1=value1\r\nkey2=value2,不进行转义。

  4、application/json

      这种方式一般在 ajax 进行批量操作操作时用的比较多,一般会结合 JSON.stringify() 函数来用。

 附录

HTTP请求报文结构图:

HTTP请求报文示例:

HTTP响应报文示例:

测试源码

using System;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.IO; namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
} /// <summary>
/// GET 方式提交
/// </summary>
[HttpGet]
public String HttpGet(string key1, string key2)
{
return string.Format("GET 方式提交: key1={0}, key2={1}", key1, key2);
} /// <summary>
/// POST 方式提交,application/x-www-form-urlencoded 编码
/// </summary>
[HttpPost]
public String HttpPostFormUrlencoded1(string key1, string key2)
{
return string.Format("POST 方式提交,application/x-www-form-urlencoded 编码: key1={0}, key2={1}", key1, key2);
} /// <summary>
/// POST 方式提交,application/x-www-form-urlencoded 编码
/// </summary>
[HttpPost]
public String HttpPostFormUrlencoded2()
{
string key1 = Request["key1"];
string key2 = Request["key2"];
return string.Format("POST 方式提交,application/x-www-form-urlencoded 编码: key1={0}, key2={1}", key1, key2);
} /// <summary>
/// POST 方式提交,multipart/form-data 编码
/// </summary>
[HttpPost]
public String HttpPostFormData1(string key1, string key2, HttpPostedFileBase file)
{
file.SaveAs(string.Format("D:\\{0}", file.FileName));
return string.Format("POST 方式提交,multipart/form-data 编码: key1={0}, key2={1},fileName={2}", key1, key2, file.FileName);
} /// <summary>
/// POST 方式提交,multipart/form-data 编码
/// </summary>
[HttpPost]
public String HttpPostFormData2()
{
string key1 = Request["key1"];
string key2 = Request["key2"];
HttpPostedFileBase file = Request.Files["file"];
file.SaveAs(string.Format("D:\\{0}", file.FileName));
return string.Format("POST 方式提交,multipart/form-data 编码: key1={0}, key2={1},fileName={2}", key1, key2, file.FileName);
} public class ParamModel
{
public string Key1 { get; set; }
public string Key2 { get; set; }
} /// <summary>
/// POST 方式提交,multipart/form-data 编码(接受Json数组)
/// </summary>
[HttpPost]
public String HttpPostFormJson()
{
string param = Request["json"];
JavaScriptSerializer jSerializer = new JavaScriptSerializer();
List<ParamModel> models = jSerializer.Deserialize<List<ParamModel>>(param);
StringBuilder sb = new StringBuilder();
foreach (ParamModel model in models)
{
sb.AppendFormat("key1={0}, key2={1}", model.Key1, model.Key2);
}
return sb.ToString();
} /// <summary>
/// POST 方式提交,application/json 编码(接受Json数组)
/// </summary>
[HttpPost]
public String HttpPostApplicationJson()
{
//如果没有指定key,可以在 InputStream 中读取数据
using (Stream inputStream = Request.InputStream)
{
using (StreamReader sr = new StreamReader(inputStream))
{
string inputString = sr.ReadToEnd();
JavaScriptSerializer jSerializer = new JavaScriptSerializer();
List<ParamModel> models = jSerializer.Deserialize<List<ParamModel>>(inputString);
StringBuilder sb = new StringBuilder();
foreach (ParamModel model in models)
{
sb.AppendFormat("key1={0}, key2={1}", model.Key1, model.Key2);
}
return sb.ToString();
}
}
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
form { display: inline-block; border: 1px solid #808080; padding: 10px; width: 400px; margin: 10px; }
form > div { margin-top: 4px; }
span { display: inline-block; width: 42px; }
input[type=text] { width: 340px; }
input[type=submit], input[type=button] { width: 344px; cursor: pointer; }
textarea { width: 338px; height: 67px; }
</style>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<form method="get" action="http://localhost:38925/Home/HttpGet">
<div>GET方式</div>
<div>
<span>key1:</span>
<input type="text" name="key1" value="111" />
</div>
<div>
<span>key2:</span>
<input type="text" name="key2" value="222" />
</div>
<div>
<span></span>
<input type="submit" value="提交" />
</div>
</form>
<form method="post" action="http://localhost:38925/Home/HttpPostFormUrlencoded1" enctype="application/x-www-form-urlencoded">
<div>POST application/x-www-form-urlencoded</div>
<div>
<span>key1:</span>
<input type="text" name="key1" value="111" />
</div>
<div>
<span>key2:</span>
<input type="text" name="key2" value="222" />
</div>
<div>
<span></span>
<input type="submit" value="提交" />
</div>
</form> <p></p> <form method="post" action="http://localhost:38925/Home/HttpPostFormData2" enctype="multipart/form-data">
<div>POST multipart/form-data(接受键值对)</div>
<div>
<span>key1:</span>
<input type="text" name="key1" value="111" />
</div>
<div>
<span>key2:</span>
<input type="text" name="key2" value="222" />
</div>
<div>
<span>文件:</span>
<input type="file" name="file" />
</div>
<div>
<span></span>
<input type="submit" value="提交" />
</div>
</form>
<form method="post" action="http://localhost:38925/Home/HttpPostFormJson" enctype="multipart/form-data">
<div>POST multipart/form-data 编码(接受Json数组)</div>
<div>
<span>Json:</span>
<textarea name="json">[{"key1":"admin11","key2":"admin12"},{"key1":"admin21","key2":"admin22"},{"key1":"admin31","key2":"admin32"},{"key1":"admin41","key2":"admin42"}]</textarea>
</div>
<div>
<span></span>
<input type="submit" value="提交" />
</div>
</form> <p></p> <form id="ajax-test">
<div>POST application/json 编码(接受Json数组)</div>
<div>
<span>key1:</span>
<input type="text" id="key11" value="key1-1" />
<span></span>
<input type="text" id="key12" value="key1-2" />
<span></span>
<input type="text" id="key13" value="key1-3" />
</div>
<div>
<span>key2:</span>
<input type="text" id="key21" value="key2-1" />
<span></span>
<input type="text" id="key22" value="key2-2" />
<span></span>
<input type="text" id="key23" value="key2-3" />
</div>
<div>
<span></span>
<input type="button" value="提交" id="ajax-submit" />
</div>
</form>
<script type="text/javascript">
$(function () {
$("#ajax-submit").click(function () {
var key11 = $("#key11").val();
var key12 = $("#key12").val();
var key13 = $("#key13").val();
var key21 = $("#key21").val();
var key22 = $("#key22").val();
var key23 = $("#key23").val();
var data = '[{"key1":"' + key11 + '","key2":"' + key21 + '"},{"key1":"' + key12 + '","key2":"' + key22 + '"},{"key1":"' + key13 + '","key2":"' + key23 + '"}]';
$.ajax({
type: "POST",
url: "http://localhost:38925/Home/HttpPostApplicationJson",
contentType: "application/json",
data: data,
success: function (msg) {
alert(msg);
}
});
});
});
</script>
</body>
</html>

HTTP协议中的报文格式的更多相关文章

  1. HTTP请求协议中请求报文(Request Headers)跟响应报文(Response Headers)的简单理解

    背景 今儿个一新来的应届生问我,开发模式中所看到的web请求的请求头里的属性怎么理解,我便根据自己的经验随便拉开一个请求跟他聊了起来,顺便自己记录下文字版,以后再有交流直接发地址给他就好了,嘻嘻,机智 ...

  2. HTTP协议中request报文请求方法和状态响应码

    一个HTTP请求报文由4部分组成: 请求行(request line) 请求头部(header) 空行 请求数据 下图给出了请求报文的一般格式: 请求行中包括了请求方法,常见的请求方法有: GET:从 ...

  3. HTTP协议报文格式

    HTTP协议报文格式 接下来我们看看HTTP协议(Hypertext Transfer Protocol――超文本传输协议)浏览器端(客户端)向WEB服务器端访问页面的过程和HTTP协议报文的格式. ...

  4. pcap报文格式

    pcap报文格式 pcap报文整体格式 pcap 报文头格式 pcap报文格式,黄色部分为报文头 pcapng报文格式 PCAPNG: PCAP Next Generation Dump File F ...

  5. ARP协议的报文格式

    原文链接地址:http://www.cnblogs.com/laojie4321/archive/2012/04/12/2444187.html   结构ether_header定义了以太网帧首部:结 ...

  6. [转]使用wireshark分析TCP/IP协议中TCP包头的格式

    本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析. 一.概述 TCP是面向连接的可靠传输协议,两个进程互发数 ...

  7. ARP协议的报文格式 转自n哖苡逅

    ARP协议的报文格式 结构ether_header定义了以太网帧首部:结构arphdr定义了其后的5个字段,其信息用于在任何类型的介质上传送ARP请求和回答:ether_arp结构除了包含arphdr ...

  8. IP封包协议头/TCP协议头/TCP3次握手/TCP4次挥手/UDP协议头/ICMP协议头/HTTP协议(请求报文和响应报文)/IP地址/子网掩码(划分子网)/路由概念/MAC封包格式

    IP协议头IP包头格式: 1.版本号:4个bit,用来标识IP版本号.这个4位字段的值设置为二进制的0100表示IPv4,设置为0110表示IPv6.目前使用的IP协议版本号是4. 2.首部长度:4个 ...

  9. 结合Wireshark捕获分组深入理解TCP/IP协议栈之TCP协议(TCP报文格式+三次握手实例)

    摘要:     本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析. 一.概述     TCP是面向连接的可靠 ...

随机推荐

  1. LM4990音频功放芯片

    我们选用的一种封装:我们用的是DGK封装. 典型电路图: 下面是示意图:四中封装的示意图是不一样的: 下面是真正的原理图: 高放大倍数的原理图: 查分式的: 单个输入的原理图: 下面是有关电源的选择:

  2. 【Codeforces Round #434 (Div. 2) B】Which floor?

    [链接]h在这里写链接 [题意] 在这里写题意 [题解] 枚举每层有多少个公寓就好. 要注意,每次都要从1到100判断,一下那个公寓该不该出现在那一层. 多个答案,如果答案是一样的.也算是唯一的.  ...

  3. [Vue] Load components when needed with Vue async components

    In large applications, dividing the application into smaller chunks is often times necessary. In thi ...

  4. 2、JNI说明

    JNI (Java Native Interface) 1. JAVA调用CLinux是用C语言写的,可以写一个APP简单调用open,read,write来访问驱动程序;Android是用Java写 ...

  5. Mac 环境下svn服务器的配置

    Mac 环境下svn服务器的配置 本文目录 • 一.创建代码仓库,用来存储客户端所上传的代码 • 二.配置svn的用户权限 • 三.使用svn客户端功能 在Windows环境中,我们一般使用Torto ...

  6. [AngularFire 2 ] Hello World - How To Write your First Query using AngularFire 2 List Observables ?

    In this lesson we are going to use AngularFire 2 for the first time. We are going to configure the A ...

  7. swift开发网络篇—利用NSURLSession 发送GET和POST请求

    说明:本文示例代码发送的请求均为http请求,需要对info.plist文件进行配置.如何配置,请参考https://github.com/HanGangAndHanMeimei/iOS9Adapta ...

  8. javascript 调用C++函数

    分3步: 一>实现IDispatch 接口 #ifndef _IDISPIMP_H_ #define _IDISPIMP_H_ // idispimp.h class CImpIDispatch ...

  9. opencv播放不了AVI视频的问题

    有些avi视频的编码可能不是Cinepak Codec by Radius编码格式的,需要转换成这种格式. 我用的是swf转avi视频,在转变换时----->设置---->AVI视频设置- ...

  10. swift学习第十五天:闭包

    闭包 闭包的介绍 闭包和OC中的block非常相似 OC中的block是匿名的函数 Swift中的闭包是一个特殊的函数 block和闭包都经常用于回调 注意:闭包和block一样,第一次使用时可能不习 ...