学习开发时间也不短了,越是深入学习,越是觉得自己的知识体系不够系统,对一些通用知识不够了解。之前看的书不少, 有一定拓展,但缺点就是少了思考及练习,窃以为写文章总结是一种很好的学习方法,当然平时还得多敲代码。这里结合 最近看的一些书以及一些开发的经历来整理一下自己对 HTTP 的理解。由于能力所限,这些总结带有猜测成分,有待日后完善。
HTTP 协议是一种应用层的通信规范。HTTP 报文本质上就是有特定格式的一些文本,报文依次通过传输层、网络层和数据 链路层和物理层的配合传递到其他主机,最后到达其应用层,接收端并按照 HTTP 规范对报文进行解析。HTTP 报文分为请求 报文和响应报文。
请求报文
请求报文一般格式如下:
POST /cgi-bin HTTP/1.1
Host: example.com
paramA=A¶mB=B
以上请求报文分为请求行、请求首部以及请求体;请求行分为请求方法、请求路径以及协议版本三个部分,每个部分以空格分隔。
常见的请求方法有 GET、POST、PUT、DELETE 等;请求协议一般为HTTP/1.1
或者HTTP/1.0
。请求首部是对请求
的详细说明,也可以将其理解为编程里的函数参数,格式为Key: Value
。例如以上的Host: example.com
是指Host
的
值为example.com
,表示要请求主机example.com
。除了 Host 还有 Content-Length 等首部。请求体与请求首部之
间以空行分隔,一般用来传输额外的数据,既可以为文本,也可以为二进制数据等。
最常用的请求方法应该是 GET 和 POST 了,也有很多文章会解释这两个方法有什么区别。最近我也看了一些类似的文章,也用 telnet 配合一些的代码进行过简单的试验。以我目前的理解,现在一般的 web 服务器都会忽略 GET 方法的请求体,也就是 说 GET 方法也是可以有请求体的,至于服务器接不接收那是另一回事。 GET 方法使用 URL 来传递参数,主要用来进行请求资源。 由于 URL 有长度的限制,所以也可以说 GET 方法传参会有长度限制。虽然 POST 方法一般都通过请求体来传递参数,但其实 也可以在 URL 上附加参数,web 服务器当然也可以接收 POST 方法通过 URL 传过来的参数了。因此 POST 方法可传输的数据 也就比 GET 方法大得多(这里也可以说 POST 可以传递无限的数据,有待查证)。 POST 方法一般用于提交数据。
响应报文
响应报文是对请求报文的应答,分为响应行、响应首部和响应体三部分。一般格式如下:
HTTP/1.1 200 OK
Content-Length: 21
Content-Type: text/html;charset=UTF-8
<h1>Hello world!</h1>
首行是响应行,分为协议版本、状态码和状态原因短语三部分,每部分以空格分隔。响应行下面是响应首部,响应首部与响应体之间以空格分隔。
浅析浏览器和 web 服务器的 HTTP 通信
一般开发并不需要了解这些知识,但了解这些知识能让自己对细节有更深的掌控。
使用现在的高级语言可以很方便地设置 Cookie、进行基本安全认证等,但是背后是怎么实现的呢?下面就以 Cookie 的设置为例, 用户通过浏览器进行登录时,登录成功后一般都会生成 Cookie,之后对其他页面的访问都会带上该 Cookie,从而浏览到个性化 内容。那么这个过程是怎样的呢?
首先,用户通过浏览器发送登录请求:
POST /account HTTP/1.1
Host: example.com
Content-Length: 22
Content-Type: application/x-www-form-urlencoded
name=user&password=pwd
一般登录成功后,web 服务器会发出如下响应报文:
HTTP/1.1 200 OK
Set-Cookie: token=123456
Content-Length: 0
Content-Type: text/html; charset=UTF-8
浏览器获取到 Set-Cookie 头后,会生成相应的 Cookie。浏览器会在背后会为通信做大量处理,因此,如果以其他方式登录,如编码请求登录 API,则 需手工处理 Set-Cookie 头。在该 Cookie 失效前,浏览器根据 Cookie 的相应参数,请求该地址的其他有效路径时会带上 Cookie,报文如下:
GET /info HTTP/1.1
Host: example.com
Cookie: token=123456
同样,Cookie 请求头也是由浏览器在背后处理,以其他方式请求时亦需手工处理 Cookie 头。
由于 Cookie 直接保存在浏览器,相对不那么安全,Session 由此而来。Session 是保存在服务端的用户配置,一般和 Cookie 搭配使用,当然,还可以通过 URL 传参等方式获取 Session。以作者使用过的语言来说,通常在设置 Session 时,如果 Cookie 可用,会自动在响应报文中添加 Cookie 头,这个 Cookie 就是获取 Session 的钥匙,Cookie 值一般是 Session 的文件名。实质上 Cookie 是保存在客户端的文件,而 Session 则是保存在服务端的文件,并没有想 象中那么神秘。
以上就是 HTTP 通信的一些简单分析。其他的 HTTP 首部与 Cookie 类似,这些 HTTP 首部就是客户端与服务端通信的语言。