从本文你将看到:HTTP是干嘛用的?怎样和服务器通信?HTTP的基本性质?HTTP能控制什么?基于HTTP三大组件系统?HTTP 和 TCP 之间的关系?HTTP 协议如何使用 TCP 连接?
本文没什么高深的东西,就是把一些概念整理了一下,大牛可以飘过,不喜勿喷
## 一、什么是HTTP
**HTTP是干嘛用的?**
HTTP学名叫做超文本传输协议,是一个网络协议。
是专门用来帮你传输诸如 HTML 的超媒体文档等 Web 内容滴。因为 HTML 本身就是超文本标记语言,HTML 中不仅有文本还有图片、音视频等内容,所以用来传输它的协议当然就叫超文本传输协议了。
比如你访问俺的博客的主页,浏览器地址栏会出现如下的网址:**http**://dunizb.com/,加了粗体的部分就是指 HTTP 协议。大部分网站都是通过 HTTP 协议来传输 Web 页面、以及 Web 页面上包含的各种东东(图片、CSS 样式、JS 脚本)。
它基于 TCP/IP 的应用层协议。它被设计用于Web浏览器和Web服务器之间的通信,但它也可以用于其他目的。
它是 Web 上数据交换的基础,是一种 client-server 协议,也就是说请求通常是由像浏览器这样的接受方发起的。一个完整的 web文档是由不同的子文档重新组建而成的,像是文本、布局描述、图片、视频、脚本等等。
**怎样和服务器通信?**
1. HTTP遵循经典的客户端-服务端模型,客户端打开一个连接以发出请求,然后等待它收到服务器端响应。 HTTP是无状态协议,意味着服务器不会在两个请求之间保留任何数据(状态)。
2. 客户端和服务端通过交换各自的消息(与数据流正好相反)来进行交互。通常由像浏览器这样的客户端发出的消息叫做 requests,那么被服务端回应的消息就叫做 responses。
HTTP 被设计于上20世纪90年代初期,**是一种可扩展性的协议。它是应用层的协议**,虽然理论上它可以通过任何可靠的传输协议来发送,但是它还是通过 TCP,或者是 TLS-加密的TCP连接来发送。因为它很好的扩展性,时至今日它不仅被用来传输超文本文档,还用来传输图片、视频或者向服务器发送如 HTML 表单这样的信息。HTTP 还可以根据网页需求,来获取部分web文档的内容来更新网页。
HTTP遵循经典的[客户端-服务端模型](https://en.wikipedia.org/wiki/Client%E2%80%93server_model),客户端打开一个连接以发出请求,然后等待它收到服务器端响应。 HTTP是[无状态协议](http://en.wikipedia.org/wiki/Stateless_protocol),意味着服务器不会在两个请求之间保留任何数据(状态)。虽然通常基于TCP / IP层,但可以在任何可靠的[传输层](https://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E5%B1%82)上使用;也就是说,一个不会静默丢失消息的协议,如UDP。
## 二、HTTP的基本性质
总述:HTTP是简单的、可扩展、无状态的
**HTTP 是简单的**
即便在HTTP/2中把HTTP消息封装到了frames中,HTTP大体上还是被设计成可读的而且简单的。HTTP的消息能够让人读懂且明白它的意思,还允许简单的测试,放低了门槛,更有利于新来者了解。
**HTTP 是可扩展的**
在HTTP/1中就出现了, HTTP headers 让协议扩展变得非常容易。只要服务端和客户端在新的headers上语义达成一致,新的功能就可以轻松地被加进来。
**HTTP 是无状态,有会话的**
HTTP是无状态的:在同一个连接中,两个成功执行的请求之间是没有关系的。这就带来了一个问题,用户没办法在一个网站进行连续的交互,比如在一个电商网站里,用户把某个商品加入了购物车中,换了一个页面后再次添加商品,两次添加商品的请求没有联系,浏览器无法知道最终用户都选择了哪些商品。而用HTTP的头部扩展,**HTTP Cookies就可以解决这个问题**(将在后面介绍)。把Cookies添加到头部中,创建一个会话来让每次请求都能共享相同的上下文信息,相同的状态。**而HTTP的核心是无状态的,cookies的使用可以创建有状态的会话。**
## 三、HTTP能控制什么
多年以来,HTTP良好的扩展性控制着越来越多Web的功能。缓存和认证方式很早就可以由HTTP来控制了。另一方面,对同源同域的限制到2010年才有所改变。
下面就是可以用HTTP来控制的常见特性。
**缓存**
文档怎么缓存能够通过HTTP来控制。服务端能告诉代理和客户端什么需要被缓存,缓存多久,而客户端能够根据请求条件首部字段(如If-Modified-Since、If-Match等)来忽略存储的文档。
**开放同源限制**
为了防止网络窥听和其它的隐私泄漏,浏览器强制对Web网站做了分割限制。只有来自于相同来源的网页才能够获取网站的全部信息。这样的限制有时反而成了负担,HTTP可以通过修改头部来开放这样的限制,因此web文档可以是由不同域下的信息拼接成的(在某些情况下,这样做还有安全因素考虑在里面)。
**认证**
一些页面能够被保护起来,仅让特定的用户进行访问。基本的认证功能可以直接通过HTTP提供,使用Authenticate相似的头部就可以,或者用HTTP cookies来设定指定的会话。
**代理和隧道**
通常情况下,服务器和/或客户端是处于内网的,对其它(外网)隐藏其真实 IP 地址。因此 HTTP 请求就要通过代理越过这个网络屏障。但并非所有的代理都是 HTTP 代理。例如,SOCKS协议的代理就运作在更底层。一些像 ftp 其它的协议也能够被它们处理。
**Cookies**
Cookies用一个服务端的状态连接起了每一个请求。这就创建了会话,虽然基本的HTTP是无状态协议。这很有用,不仅是因为能用到购物车这样的电商业务上,更是因为,它使得任何网站都能够配置页面展现的东西了。
## 四、基于HTTP三大组件系统
**客户端:user-agent**
严格意义来说,user-agent 就是任何能够为用户发起行为的工具。但实际上,这个角色通常都是由浏览器来扮演。对于发起请求来说,浏览器总是作为发起一个请求的实体,而永远不是服务器(虽然一些机制已经能够模拟服务器发起请求的消息了)。
**Web服务端**
在上述通信过程的另一端,就是一个Web Server来服务并提供客户端请求的文档。Server只是虚拟意义上:它可以是许多共同分担负载(负载平衡)的一组服务器组成的计算机群,也可以是一种复杂的软件,通过向其他计算机发起请求来获取部分或全部资源的软件。
Server不再只是一个单独的机器,它可以是在同一个机器上装载的许多服务之一。在HTTP/1.1和Host头部中,它们甚至可以共享同一个IP地址。
**Proxies 代理**
在浏览器和服务器之间,有许多计算机和其他设备转发了HTTP的消息。因为Web栈层次结构的原因,它们大多数都出现在传输层、网络层和物理层上,对于HTTP的应用层来说就是透明的(虽然它们可能会对应用层的性能有重要影响)。而还有一部分表现在应用层上的,就叫做proxies了。Proxies既可以表现得透明,又可以不透明(看请求是否通过它们),主要表现在这几个功能上:
* 缓存(可以是公开的或是私有的,像浏览器的缓存)
* 过滤(像反病毒扫描,家长监护)
* 负载均衡,让多个服务器服务不同的请求
* 对不同资源的权限控制
* 登陆,允许存储历史信息
每一个发送到服务器的请求,都会被服务器处理并且返回一个消息,也就是response。在client与server之间,还有许许多多的被称为proxies的实体,他们的作用与表现各不相同,比如有些是网关,还有些是caches等。

实际上,在一个浏览器和处理请求的服务器之间,还有计算机、路由器、调制解调器等等许多实体。由于Web的层次设计,那些在网络层和传输层都不可见了。HTTP是在最上层应用层中的,虽然下面的层次对分析网络问题非常重要,但是对HTTP的描述来说,这些大多数都是不相关的。
## 五、HTTP 和 TCP 之间的关系
前面说过,HTTP是基于 TCP/IP 的,简单地说,TCP 协议是 HTTP 协议的基石——HTTP 协议需要依靠 TCP 协议来传输数据。
在网络分层模型中,TCP 被称为“传输层协议”,而 HTTP 被称为“应用层协议”。有很多常见的应用层协议是以 TCP 为基础的,比如“FTP、SMTP、POP、IMAP”等。
TCP 被称为“面向连接”的传输层协议。关于它的具体细节,俺就不展开了(否则篇幅又失控了)。你只需知道:传输层主要有两个协议,分别是 TCP 和 UDP。TCP 比 UDP 更可靠。你可以把 TCP 协议想象成某个水管,发送端这头进水,接收端那头就出水。并且 TCP 协议能够确保,先发送的数据先到达(与之相反,UDP 不保证这点)。
## 六、HTTP 协议如何使用 TCP 连接?
HTTP 对 TCP 连接的使用,分为两种方式:俗称“短连接”和“长连接”(“长连接”又称“持久连接”,洋文叫做“Keep-Alive”或“Persistent Connection”)
假设有一个网页,里面包含好多图片,还包含好多 外部的 CSS 文件和 JS 文件。在“短连接”的模式下,浏览器会先发起一个 TCP 连接,拿到该网页的 HTML 源代码(拿到 HTML 之后,这个 TCP 连接就关闭了)。然后,浏览器开始分析这个网页的源码,知道这个页面包含很多外部资源(图片、CSS、JS)。然后针对 每一个 外部资源,再分别发起一个个 TCP 连接,把这些文件获取到本地(同样的,每抓取一个外部资源后,相应的 TCP 就断开)
相反,如果是“长连接”的方式,浏览器也会先发起一个 TCP 连接去抓取页面。但是抓取页面之后,该 TCP 连接并不会立即关闭,而是暂时先保持着(所谓的“Keep-Alive”)。然后浏览器分析 HTML 源码之后,发现有很多外部资源,就用刚才那个 TCP 连接去抓取此页面的外部资源。
在 HTTP 1.0 版本,默认使用的是“短连接”(那时候是 Web 诞生初期,网页相对简单,“短连接”的问题不大).
到了1995年底开始制定 HTTP 1.1 草案的时候,网页已经开始变得复杂(网页内的图片、脚本越来越多了)。这时候再用短连接的方式,效率太低下了(因为建立 TCP 连接是有“时间成本”和“CPU 成本”滴)。所以,在 HTTP 1.1 中,默认采用的是“Keep-Alive”的方式。
## 七、一些术语
**资源(resource)**
Web资源是使用URL指向的Web内容。
* 内容可以是静态的,如:文本文件、HTML文件、JPEG文件。
* 或者是动态的内容。如:摄像头的实时采集软件生成的动态影像,用户填写的电子网站订单。
**资源类型**
Web服务器会为所有HTTP资源赋予一个类型,以便于HTTP软件处理消息主体。如,用 text/html 标记 html。可以再看两个案例:
* text/plain :ASCII文本文档
* image/jpeg :JPEG版本的图片
非常多的资源类型和文本标记的对应关系,一起构成了一个超长的清单,并且由RFC 2045标准化。此标准被称为MIME。MIME是Multipurpose Internet Mail Extension的缩写。虽然名称很长,但是含义简单,就是用来指定消息内的实体类型的。之所以有Mail字样,是因为最初设计是为了Mail的异构系统交换文档的。
**资源标示符**
URL是一种资源位置标示方法。URL描述了一个资源在服务器上的位置。这就是一个合法的URL:[http://example.com/part/index...](http://example.com/part/index.htm)。
* 第一部分:方案(scheme)。指明了访问资源所使用的协议类型。这部分通常是HTTP协议([http://)](http://%29/)。
* 第二部分:服务器地址(比如,example.com)。
* 其余部分指定了Web服务器上的某个资源(比如,/part/index.htm)。
当在地址栏输入此资源名并回车后,用户代理会把URL解析,把必要的信息以HTTP协议的要求,打入请求消息内。以[http://www.example.com/index....](http://www.example.com/index.html),变成
~~~
GET index.html HTTP/1.1
host:www.example.com
空行
~~~
打开到www.example.com的tcp连接,并发送此请求消息给服务器,然后等待服务器响应并解析显示给用户。
> 更多URL、URI、URN详细推荐阅读:[《你知道URL、URI和URN三者之间的区别吗?》](http://web.jobbole.com/83452/)
**HTTP事务**
一个HTTP事务由一条请求消息和一个响应消息构成。
**HTTP方法**
HTTP支持几种不同的请求命令,这些命令被称为HTTP方法(HTTP method)。每条HTTP请求报文都包含一个方法。
**状态码**
每条HTTP响应消息返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是需要采取其他行动。
**消息**
从Web客户端发往Web服务器的HTTP报文称为请求消息。从服务器发往客户端的消息称为响应消息。HTTP报文包括三部分:
~~~
起始行
首部字段
主体
~~~
如发送一个hello.htm 的资源给客户端,请求消息是:
~~~
GET /hello.html HTTP/1.1
~~~
请求消息只有起始行,指明使用的HTTP方法、资源的URL,以及协议的版本。没有首部字段和主体。
响应消息为:
~~~
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 22
ETag: W/"16-FmHX0hamHjYkHeAP/7PfzA"
Date: Thu, 03 Dec 2015 09:54:01 GMT
Connection: close
<h1>Hello, World!</h1>
~~~
这个消息第一行为起始行,指明协议版本、状态码(200表示成功)和状态说明(OK)。接下来一直到空行之间都是首部字段,用来说明服务器、资源类型、内容长度、生成文档时间等。空行后就是主体,这里就是一个html文件的内容。实际上,主体可以承载任何内容,而不限于文本。
## 总结
HTTP是一个简单快速、灵活、无连接、无状态的超文本传输协议。
HTTP是很简单可扩展的一种协议。结合了轻松添加头部信息能力的Client-server结构使得HTTP可以和Web的功能扩充一同发展。
即使HTTP/2为了提高性能把HTTP报文嵌到帧中这一举措增加了复杂度,但是从Web应用的角度来看,报文的基本结构是没有变化的,从HTTP/1.0发布起就是相同的。
* * *
关于HTTP,如果你不想啃大部头的《HTTP权威指南》,那么强烈建议你阅读刘传君的图灵电子书《HTTP小书》,准能帮你节省不少时间,只要9块钱!戳这里:[http://www.ituring.com.cn/book/1791](http://www.ituring.com.cn/book/1791)
- 关于我
- nginx
- 代理
- 实例1
- 使用Nginx实现反向代理
- nginx反向代理配置
- Nginx缓存原理及配置
- nginx 信号集
- rewrite
- nginx rewrite规则
- nginx rewrite 正则规则详解
- nginx+php-fpm fastcgi防止跨站、跨目录的安全设置
- 写了个shell脚本,实现nginx日志自动切割,并利用goaccess分析成HTML报表,然后通知管理人员查阅
- nginx禁止一些常见的不应该让用户访问的文件
- PHP
- 实现PHP多进程管理
- php代码规范
- Linux
- 常用命令
- scp
- touch
- nohup
- rsync
- ssh命令 远程登录
- chmod
- nginx日志切割脚本
- Linux使用ssh公钥实现免密码登录Linux
- 使用ssh公钥密钥自动登陆linux服务器
- Linux查看程序端口占用情况
- ssh 公钥私钥认证原理
- 路由图
- CentOS7防火墙设置
- linux下用户管理
- Linux 服务器安全技巧
- Linux shell 提取文件名和目录名
- Linux环境下设置命令别名(alias)
- Git
- 搭建Git服务器
- 手把手教你搭建git服务器
- Git 基本操作
- git删除文件夹/文件(不删除本地文件)
- git忽略文件和文件夹以及文件权限
- Git的四个区五种状态
- git init 和 git init --bare 的区别
- git仓库删除所有提交历史记录,成为一个干净的新仓库
- 如何正确使用Git Flow
- HTTP
- 前端跨域解决方案
- HTTP基本概念
- Redis
- Redis 数据类型及应用场景
- JavaScript
- WebSocket探秘
- socket与websocket的区别
- 基于 Swoole 的微信扫码登录
- Web前端开发规范手册
- 简单的学习了一下ES6
- ES6模块的import和export用法
- MySql
- MySql重置root密码的方法
- mysql 5.6.30 开启慢查询日志
- mysql查看锁表情况
- 我的设计稿
- 会计出纳系统
- 上门宝ERP系统
- 社交应用七大需求
- 出纳系统
- 利用SdfMpp搭建中大行软件系统
- B2C库存商品系统
- 软件
- 网上商城
- 思维逻辑
- 系统架构分层图
- 代码检查规范
- 研发计划
- 系统架构
- 我设计的架构架构图
- 电商网站架构案例
- 大型网站架构
- 服务熔断、降级、限流、异步RPC
- 软件版本号规范
- 第三方服务引擎
- kafka
- ElasticSearch
- 阿里云 推荐引擎
- 随记
- 人生最大的投资
- 产品研发团队管理的6个方面
- 我感觉自己根本不是一个创业者,更谈不上企业家,果然还是屌丝这个称呼更适合我。
- 学什么语音都应该养成的编程习惯
- 2018年5月23日 多云转阴 15-24°C 离职信
- 2017年12月25日
- 对“目标”的认知
- 个人简历
- API设计
- 理解OAuth 2.0
- OAuth 2.0四种授权方式小结
- 对 REST 的理解
- RESTful API 设计指南
- RESTful API 设计
- RPC
- 微服务架构方案
- SOA
- 理解RESTful架构
- RESTful API GET,DELETE,PUT和POST的响应状态码
- MongoDB
- MongoDB-无法启动的一个问题