supce's blog

HTTP之概述


去看瓷器古董的时候,如果卖家直接把瓷器递给买家,容易失手掉下去,也不好判定到底是谁的责任。于是有了这样一条规矩:卖家会把瓷器放在桌子上,离手之后,买家再去拿。这样既保证了瓷器在传递过程中的安全性,也容易分辨是谁失手打碎的瓷器。

Web客户端和服务器

上面这条规矩规定了贵重瓷器是如何在买家与卖家之间传递而不被破坏的。大家都知道Web内容都是存在Web服务器上的。那么Web客户端(最常见的是浏览器)与服务器之间的信息什么时候传递、如何传递、具体传递什么,并且能够保证数据在传输过程中不会被损坏或产生混乱?于是就有了HTTP。

HTTP是超文本传输协议的英文缩写。既然要保证传输过程中数据不被损坏,说明HTTP是一种可靠的数据传输协议。当我们想浏览某个页面时,浏览器会向服务器发送一个HTTP请求。服务器会寻找所期望的对象,如果存在,就将对象、对象类型。对象长度以及其他的一些信息放在HTTP响应中发送给客户端。

下图可能会更加直观:

上图可以发现,要想浏览一个页面,最主要的是HTTP请求和HTTP响应。现实中,如果我们想去张三家,首先得知道他的家庭住址。HTTP请求也是一样,在发送请求时,必须知道请求的资源具体在哪,这就需要借助URL。URL是统一资源定位符的英文缩写,它描述了一台特定服务器上某个资源的特定位置。一个具体的URL实例如下图:

下面就具体看看一次HTTP请求和响应是怎样的。比如,我们想要访问Baidu的首页,借助chrome,首先查看请求头:

第一行为:GET / HTTP/1.1 HTTP支持几种不同的请求命令,这些命令被称为HTTP Method。每条HTTP请求都包含一个方法,这个方法会告诉服务器具体执行什么动作。下图是五种常见的HTTP方法:

对于HTTP/1.1是现在使用的HTTP协议的版本。

第二行host是这次请求的主机。

第三行Connection: keep-alive keep-alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,keep-alive功能避免了建立或者重新建立连接。

下一行为Cache-Control: max-age=0 Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached。其中,max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。

然后是Upgrade-Insecure-Requests: 1 这个是和https有关。服务器的响应头有时候可能会有Content-Security-Policy: upgrade-insecure-requests,该指令用于让浏览器自动升级请求从http到https,用于大量包含http资源的http网页直接升级到https而不会报错。简洁的来讲,就相当于在http和https之间起的一个过渡作用。而对于请求头的Upgrade-Insecure-Requests:1,则是告诉服务器,自己支持这种操作,也就是我能读懂你服务器发过来的上面这条信息,并且在以后发请求的时候不用http而用https。

具体可以参考小胡子哥的一篇blog

再往下是User-Agent,它包含了发出请求的用户信息,通常是用户操作系统、浏览器版本、内核等。

再下面三个是客户端希望接收的数据类型、数据编码方式和支持的语言。

最后则是我们的Cookie。

下面再来分析下响应头,具体的响应头如下图

第一行为:200 OK 我们把它称为状态码。每条HTTP响应报文返回时都会携带一个状态码,状态码是一个三位数的代码,告知客户端请求是否成功,或者采取其他的动作。下图为几种常用的状态码:

有些人访问Google,说404了,其实是不正确的。

第二行为:Server: bfe/1.0.8.18 Server响应头包含处理请求的原始服务器的软件信息。BFE全称是Baidu Front End,是百度自己研发的一套前端接入系统。查看网易官网是 Server:nginx

再往下是Date头域,它表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。

之后是Content-Type: text/html;charset=utf-8,浏览器会根据Content-Type来决定如何显示返回的消息体内容。HTML格式的文本文档由text/html类型来标记。其他常用类型如下图:

然后再看Cache-Control: private,和请求头不太一样,对于响应消息中的指令,具体包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当前用户的部分响应消息,此响应消息对于其他用户的请求无效。

X-UA-Compatible: IE=Edge,chrome=1 这里是设置浏览器的兼容模式,强制浏览器按照特定的版本标准进行渲染。百度这里设置IE渲染模式是照最高的标准模式解析页面,chrome=1则可以激活Chrome Frame。

然后是Strict-Transport-Security: max-age=604800,trict Transport Security(通常简称为HSTS)是一个安全功能,它告诉浏览器只能通过HTTPS访问当前资源,禁止HTTP方式。

最后是我们的响应主体,也就是网页的具体内容:


TCP/IP

上面主要是浏览器发送请求,然后服务器做出响应,浏览器解析完响应后把内容呈现。但是,从服务器到浏览器这一过程的信息又是如何传递的呢?这就需要祭出计算机网络课程里的一张图了:

由上图可以看出,HTTP是个应用层的协议。HTTP并不关心网络通信的具体细节,它把联网的细节都交给了通用、可靠的TCP/IP协议。简单来说HTTP协议位于TCP/IP的上层,浏览器与服务器之间是HTTP使用TCP来传输数据。至于TCP/IP的详细内容以后再专门拿一篇文章来讲。这里主要说的还是浏览器与服务器通信的一个大致过程。

最后用一张图再来解释一下浏览器与服务器的连接与处理: