按照传输过程,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. Altium Designer如何改两个原件之间的安全距离

    在pcb中按 D R 一个事垂直距离, 另一个是水平距离.

  2. 双向链表(自己写的c++类)

    UVA还是上不去T T哭瞎了. 只好老老实实的研究上回买的书了. 写得有点长.好吧,我只是来复习C++类的. 特意用class 而不用struct写链表. 数据结构还没学...双向链表就当先预习了. ...

  3. 把git仓库从码云迁到github,及git常用命令

    前言 刚开始建仓库的时候,因为网络的原因选择了国内的码云.后来又想换成github,毕竟平时github使用率比较高. 替换远程仓库地址方式如下: git remote set-url origin ...

  4. css选择器.md

    css选择器总结 1.元素选择器 如:*{},body{},p{} ; xml中note{},to{},from{} 2.class与id选择器 如:.class{},#id{} 3.伪类选择器 选择 ...

  5. proxool数据库连接池用法

    今天给大家介绍一种新的数据连接池实现方式--proxool数据库连接池,这是一个健壮.易用的连接池.以下通过一个Demo说明一下怎样使用: 项目结构例如以下: DBLink.java文件里的代码: p ...

  6. HDU 1248 寒冰王座 完全背包

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1248 中文题,大意就不说了. 第一道完全背包题,跟着背包九讲做的. 和0-1背包的区别在于所不同的是每种 ...

  7. 9、LCD驱动程序框架

    linux-3.4.2\drivers\video\S3C2410fb.c(内核自带驱动程序) fbmem.c是LCD驱动程序顶层框架文件,是一个通用的文件,在初始化init函数中会注册一个字符设备, ...

  8. BAPC2014 C&amp;&amp;HUNNU11583:Citadel Construction(几何)

    题意: 给出一系列的点,要求寻找最多4个点.使得组成一个面积最大的多边形 思路: 非常显然仅仅有两种情况.要么是三角形,要么是四边形 首先不难想到的是.先要把最外面的点都找出来,事实上就是找凸包 可是 ...

  9. js进阶正则表达式5几个小实例(原样匹配的字符在正则中原样输出)(取反^)

    js进阶正则表达式5几个小实例(原样匹配的字符在正则中原样输出)(取反^) 一.总结 原样匹配的字符在正则中原样输出:var reg4=/第[1-2][0-9]章/g //10-29 取反^:var ...

  10. JMS是一种应用于异步消息传递的标准API

    JMS是一种应用于异步消息传递的标准API,作为Java平台的一部分,JMS可以允许不同应用.不同模块之间实现可靠.异步数据通信.一些概念 JMS provider    An implementat ...