最近在看《图解HTTP》。全书以图解的形式生动形象的讲解了HTTP协议。本文是根据该书整理的笔记,方便以后回顾。

HTTP的诞生

HTTP又称超文本传输协议(HTTP,HyperText Transfer Protocol)。

HTTP是互联网上应用最为广泛的一种网络协议,用于从万维网(WWW)服务器传输超文本到本地浏览器。所有的www文件都必须遵守这个标准。

设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。

1960年美国人Ted Nelson构思了一种通过计算机处理文本信息的方法,并称之为超文本(hypertext),这成为了HTTP超文本传输协议标准架构的发展根基。

Ted Nelson组织协调万维网协会(World Wide Web Consortium)和互联网工程工作小组(Internet Engineering Task Force )共同合作研究,最终发布了一系列的RFC,其中著名的RFC 2616定义了HTTP/1.1

HTTP的历史:

HTTP/0.9 已过时。只接受 GET 一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持 POST 方法,所以客户端无法向服务器传递太多信息。

HTTP/1.0 这是第一个在通讯中指定版本号的HTTP 协议版本,至今仍被广泛采用,特别是在代理服务器中。

HTTP/1.1 当前版本。持久连接被默认采用,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。

HTTP与TCP/IP

TCP/IP协议

TCP/IP是为了解决全世界计算机互联问题而出现的通信协议。早期的计算机网络,都是由各厂商自己规定一套协议,IBM、Apple和Microsoft都有各自的网络协议,互不兼容。虽然互联网协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP协议,所以,大家把互联网的协议简称TCP/IP协议。

TCP/IP 定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准。

在 TCP/IP 中包含一系列用于处理数据通信的协议:

  • TCP (传输控制协议) - 应用程序之间通信
  • UDP (用户数据包协议) - 应用程序之间的简单通信
  • IP (网际协议) - 计算机之间的通信
  • ICMP (因特网消息控制协议) - 针对错误和状态
  • DHCP (动态主机配置协议) - 针对动态寻址

IP协议

通信的时候,双方必须知道对方的标识。互联网上每个计算机的唯一标识就是IP地址,类似123.123.123.123。如果一台计算机同时接入到两个或更多的网络,比如路由器,它就会有两个或多个IP地址,所以,IP地址对应的实际上是计算机的网络接口,通常是网卡。

IP协议负责把数据从一台计算机通过网络发送到另一台计算机。数据被分割成一小块一小块,然后通过IP包发送出去。由于互联网链路复杂,两台计算机之间经常有多条线路,因此,路由器就负责决定如何把一个IP包转发出去。IP包的特点是按块发送,途径多个路由,但不保证能到达,也不保证顺序到达。

TCP协议则是建立在IP协议之上的。TCP协议负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。TCP协议会通过握手建立连接,然后,对每个IP包编号,确保对方按顺序收到,如果包丢掉了,就自动重发。

许多常用的更高级的协议都是建立在TCP协议基础上的,比如用于浏览器的HTTP协议、发送邮件的SMTP协议等。

简单的HTTP协议

HTTP协议工作于客户端-服务端架构为上。

  • HTTP协议规定,请求从客户端发出,最后服务器响应该请求并返回。
  • HTTP协议是无状态的。HTTP协议不会对请求和响应之间的通信状态进行保存。但HTTP引入的Cookie技术可以保持状态。
  • HTTP协议使用URI定位互联网上的资源。

请求URI的方式有多种:

1)完整的URI:

GET http://52fhy.com/index.html HTTP/1.1

2)分开写:

GET /index.html HTTP/1.1
Host: 52fhy.com

3)除此之外,如果不是对服务器上的资源进行访问,而是对服务器本身发起请求,可以用*来代替URI:

OPTIONS * HTTP/1.1
  • HTTP请求方法:

|方法|说明|支持的HTTP协议版本|

|--|--|

|GET| 获取资源|1.0, 1.1|

|POST| 传输实体主体|1.0, 1.1|

|PUT| 传输文件|1.0, 1.1|

|HEAD| 获得报文首部|1.0, 1.1|

|DELETE| 删除文件|1.0, 1.1|

|OPTIONS| 询问服务器支持的方法|1.1|

|TRACE| 追踪路径|1.1|

|CONNECT| 要求用隧道协议连接代理|1.1|

|LINK|建立和资源的联系|1.0|

|UNLINK|断开连接关系|1.0|

  • HTTP使用Keep-alive建立持久连接。初始版本的HTTP协议每进行一次通信就要断开一次连接。HTTP/1.1和一部分的HTTP/1.0想出了持久连接。

HTTP报文

用于HTTP协议交互的信息称为HTTP报文。HTTP报文本质上是字符串文本。

根据请求的端来区分,HTTP报文可以分为请求报文(客户端的HTTP报文)和响应报文(服务器端的HTTP报文)。

根据报文结构,HTTP报文可以分为报文首部报文主体。通常,不一定有报文主体。但报文首部是必须的。

报文首部
(空行 CR+LF,即回车换行)
报文主体

示例(报文主体为空):

GET /index.html HTTP/1.1
Host: 52fhy.com
Connection: keep-alive

请求报文和响应报文

请求报文格式:

GET请求:

GET /path HTTP/1.1
Header1: Value1
Header2: Value2
Header3: Value3

POST请求:

POST /path HTTP/1.1
Header1: Value1
Header2: Value2
Header3: Value3 body data goes here...

报文首部和报文主体通过CR+LF(Python里是\r\n\r\n)来分隔的。

响应报文格式:

HTTP/1.1 200 OK
Header1: Value1
Header2: Value2
Header3: Value3 body data goes here...

HTTP响应如果包含body,也是通过CR+LF(Python里是\r\n\r\n)来分隔的。

请求报文和响应报文的内容由以下几部分组成:

  • 请求行,例如GET /path HTTP/1.1,包含用于请求的方法、请求的URI和协议版本;
  • 状态行,例如HTTP/1.1 200 OK,包含协议版本、响应结果的状态码、状态码说明;
  • 首部字段,包含请求和响应的各种条件和属性的各类首部。一般有4种首部:通用首部、请求首部、响应首部、实体首部。
  • 其它,可能包含HTTP的RFC未定义的部分,如Cookie等。

报文编码

HTTP在传输时可以通过编码来提升传输速率。编码的工作会消耗更多的CPU等资源。

内容编码:

用于将报文主体进行压缩。内容编码后的实体由客户端接收并负责解码。

常用的内容编码:gzip、compress、deflate、identity(不进行编码)。

分块传输编码:

在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。

HTTP状态码

HTTP状态码负责表示客户端请求的返回结果、标记服务端的处理是否正常、通知出现的错误等工作。

借助状态码,我们可以知道服务器端是正常处理了请求,还是出错了。

状态码由3位数字和英文原因短语组成。

状态码类别

状态码有5种类别:

类别 说明 原因短语
1XX 信息性状态码 接收的请求正在处理
2XX 成功状态码 请求正常
3XX 重定向状态码 需要进行附加状态以完成请求
4XX 客户端错误状态码 服务端无法处理请求
5XX 服务端错误状态码 服务端处理请求出错

只要遵守状态码类别的定义,即使改变RFC2616中定义的状态码,或服务器自行创建状态码都没有问题。

状态码详解

仅记录在RFC2616中的状态码就有40种,再加上WebDAV和附加HTTP状态码(RFC6585),数量达60余种。但常用的就14种:200,204,206,301,302,303,304,307,400,401,403,404,500,503。详细定义见下面描述。

  • 1xx 信息

    表示临时响应并需要请求者继续执行操作的状态代码。
100 (继续) 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。
101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。
  • 2xx 成功

    表示成功处理了请求的状态代码。
200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
201 (已创建) 请求成功并且服务器创建了新的资源。
202 (已接受) 服务器已接受请求,但尚未处理。
203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206 (部分内容) 服务器成功处理了部分 GET 请求。
  • 3xx 重定向

    表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
  • 4xx 客户端错误

    这些状态代码表示请求可能出错,妨碍了服务器的处理。
400 (错误请求) 服务器不理解请求的语法。
401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403 (禁止) 服务器拒绝请求。
404 (未找到) 服务器找不到请求的网页。
405 (方法禁用) 禁用请求中指定的方法。
406 (不接受) 无法使用请求的内容特性响应请求的网页。
407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408 (请求超时) 服务器等候请求时发生超时。
409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。
  • 5xx 服务器错误

    这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

参考

1、TCP/IP简介 - 廖雪峰的官方网站

http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014320037768360d53e4e935ca4a1f96eed1c896ad1217000

2、TCP/IP 介绍 | 菜鸟教程

http://www.runoob.com/tcpip/tcpip-intro.html

3、HTTP 教程 | 菜鸟教程

http://www.runoob.com/http/http-tutorial.html

4、HTTP状态码详解

http://tool.oschina.net/commons?type=5

HTTP笔记(一)的更多相关文章

  1. git-简单流程(学习笔记)

    这是阅读廖雪峰的官方网站的笔记,用于自己以后回看 1.进入项目文件夹 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file ...

  2. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  3. SQL Server技术内幕笔记合集

    SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...

  4. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  5. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  6. NET Core-学习笔记(三)

    这里将要和大家分享的是学习总结第三篇:首先感慨一下这周跟随netcore官网学习是遇到的一些问题: a.官网的英文版教程使用的部分nuget包和我当时安装的最新包版本不一致,所以没法按照教材上给出的列 ...

  7. springMVC学习笔记--知识点总结1

    以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...

  8. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  9. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  10. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

随机推荐

  1. VS2010环境下用ANSI C创建DLL和使用方法(转)

    源:VS2010环境下用ANSI C创建DLL和使用方法 . 创建DLL工程 1.2 创建一个dll工程. 操作:a.文件->新建->项目->Win32控制台应用程序. b.输入工程 ...

  2. 【转载】Eclipse 断点调试

      作为开发人员,掌握开发环境下的调试技巧十分有必要.去年就想把关于Eclipse断点调试总结下了,由于对时间的掌控程度仍需极大提高,结果拖到今年才写了此篇博文.关于Java调试技术还有很多,如Jav ...

  3. .net面试题【持续更新.....】

    1.C#中readonly和const的区别? 2.C#中的排序继承自哪个接口?Icompare 3.阐述单点登录的实现原理? 4.C#中property和Attribute的区别? 5.Datase ...

  4. 深入理解yield(转)

    yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法.只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子: def addlist(a ...

  5. c++初学(电梯实验)

    模拟电梯载人实验 Elevator.h class Elevator{public:    Elevator();    ~Elevator();    void getNowNum();       ...

  6. pku2104

    传送门:http://poj.org/problem?id=2104 题目大意:给定一个长度为N的数组{A[i]},你的任务是解决Q个询问.每次询问在A[l], A[l+1], ...... , A[ ...

  7. bzoj2453

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2453 题目大意: (1)       若第一个字母为“M”,则紧接着有三个数字L.R.W.表 ...

  8. Aptana插件安装、配置

    本文讲解在线安装的方式: 1.eclipse->help->Install New SoftWare... 在弹出的对话框Work with中填入[http://download.apta ...

  9. Android应用性能优化方案

    1.避免创建不必要的对象 2.如果方法用不到成员变量,可以把方法声明为静态(static),这样性能会提高百分之十五到百分之二十 3.避免使用get/set存取字段,可以把字段声明为public直接访 ...

  10. 限制EditText的输入字数

    private EditText edit_student_name; edit_student_name.addTextChangedListener(changeStudentNameWatche ...