HTTP协议中的报文格式
按照传输过程,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协议中的报文格式的更多相关文章
- HTTP请求协议中请求报文(Request Headers)跟响应报文(Response Headers)的简单理解
背景 今儿个一新来的应届生问我,开发模式中所看到的web请求的请求头里的属性怎么理解,我便根据自己的经验随便拉开一个请求跟他聊了起来,顺便自己记录下文字版,以后再有交流直接发地址给他就好了,嘻嘻,机智 ...
- HTTP协议中request报文请求方法和状态响应码
一个HTTP请求报文由4部分组成: 请求行(request line) 请求头部(header) 空行 请求数据 下图给出了请求报文的一般格式: 请求行中包括了请求方法,常见的请求方法有: GET:从 ...
- HTTP协议报文格式
HTTP协议报文格式 接下来我们看看HTTP协议(Hypertext Transfer Protocol――超文本传输协议)浏览器端(客户端)向WEB服务器端访问页面的过程和HTTP协议报文的格式. ...
- pcap报文格式
pcap报文格式 pcap报文整体格式 pcap 报文头格式 pcap报文格式,黄色部分为报文头 pcapng报文格式 PCAPNG: PCAP Next Generation Dump File F ...
- ARP协议的报文格式
原文链接地址:http://www.cnblogs.com/laojie4321/archive/2012/04/12/2444187.html 结构ether_header定义了以太网帧首部:结 ...
- [转]使用wireshark分析TCP/IP协议中TCP包头的格式
本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析. 一.概述 TCP是面向连接的可靠传输协议,两个进程互发数 ...
- ARP协议的报文格式 转自n哖苡逅
ARP协议的报文格式 结构ether_header定义了以太网帧首部:结构arphdr定义了其后的5个字段,其信息用于在任何类型的介质上传送ARP请求和回答:ether_arp结构除了包含arphdr ...
- IP封包协议头/TCP协议头/TCP3次握手/TCP4次挥手/UDP协议头/ICMP协议头/HTTP协议(请求报文和响应报文)/IP地址/子网掩码(划分子网)/路由概念/MAC封包格式
IP协议头IP包头格式: 1.版本号:4个bit,用来标识IP版本号.这个4位字段的值设置为二进制的0100表示IPv4,设置为0110表示IPv6.目前使用的IP协议版本号是4. 2.首部长度:4个 ...
- 结合Wireshark捕获分组深入理解TCP/IP协议栈之TCP协议(TCP报文格式+三次握手实例)
摘要: 本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析. 一.概述 TCP是面向连接的可靠 ...
随机推荐
- [Angular] Reactive Store and AngularFire Observables
A simple store implemenet: import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } ...
- 嵌入式Linux学习笔记 NAND Flash控制器
一.NAND Flash介绍和NAND Flash控制器的使用 NAND Flash在嵌入式系统中的作用,相当于PC上的硬盘 常见的Flash有NOR Flash和NAND Flash,NOR Fla ...
- DOS 命令forfiles
forfiles /p E:/dbbackup/diff /s /m *.* /d -14 /c "cmd /c del @file" forfiles: /p 指定的路径 /s ...
- jQuery常用方法(持续更新) jQuery(转)
0.常用代码: 请容许我在1之前插入一个0,我觉得我有必要把最常用的代码放在第一位,毕竟大部分时间大家都是找代码的. (1)AJAX请求 $(function() { $('#send').click ...
- [Nuxt] Add Arrays of Data to the Vuex Store and Display Them in Vue.js Templates
You add array of todos to the store simply by adding them to the state defined in your store/index.j ...
- BestCoder Round #11 (Div. 2) 前三题题解
题目链接: huangjing hdu5054 Alice and Bob 思路: 就是(x,y)在两个參考系中的表示演全然一样.那么仅仅可能在这个矩形的中点.. 题目: Alice and Bob ...
- stm32优先级
- 【Codeforces Round #185 (Div. 2) D】Cats Transport
[链接] 链接 [题意] 有n座山,m只猫. 每只猫都在其中的一些山上玩. 第i只猫在h[i]山上玩,且会在t[i]时刻出现在山脚下(然后就一直在那里等) 然后有p个人. 它们听从你的安排. 在某个时 ...
- Auto Layout深入理解,及masonry简单介绍
本篇博客是本人在学习自己主动布局过程中对自己主动布局的理解和整理,分三部分介绍,内容可能会有所反复.见谅. 一.autosizing与Auto Layout对照,及Auto Layout简单介绍 1. ...
- js进阶 11-17 juqery如何查找一个元素的同级元素
js进阶 11-17 juqery如何查找一个元素的同级元素 一.总结 一句话总结:三个方法,向前(prev()),向后(next())和兄弟(siblings()),而前面两个每个都对应三个,pre ...