重新学习web后端开发-003-了解http请求

重新学习web后端开发-003-了解http请求

语言作为工具,对于我们之重要,正如骏马对骑士的重要,最好的骏马适合于最好的骑士,最好的语言适合于最好的思想。—— 但丁

1. http协议发展

自1991年发布第一个HTTP版本V0.9标准以来,经过了多年的发展,最新的HTTP版本V2已于2015年发布,同时下一代版本HTTP V3也在制定中。然而,当前使用最为广泛的是1.1版本,同时正在往2.0版本过渡,后续文章中将会介绍HTTP/2的情况,相较之前的版本,2.0版本有非常大的变化。

发布时间版本特点相关文档
19910.9该版本极其简单,只有一个命令GET
19961.0支持任何格式的内容,协议格式变化。新增功能还包括
状态码(status code)、多字符集支持、
多部分发送(multi-part type)、权限(authorization)、
缓存(cache)、内容编码(content encoding)等。
19971.1持久连接、管道机制、分块传输编码、
新增了许多动词方法:PUTPATCHHEAD
OPTIONSDELETE 、请求的头信息新增了Host字段
RFC 7230 ~ 7235
20152.0二进制协议、多工、数据流、头信息压缩、服务器推送RFC 7540
提示:后续如无特殊说明,都以http v1.1为准。

2. http请求

在上篇文章中,我们向"/hello"发起了一个http请求,下面具体分析一下。

GET /hello HTTP/1.1
Host: localhost:9800
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7

<上面一行是一个空行CRLF, 同时请忽略本行的说明文字>

其中,第1行是请求行,第2-10行都是请求头,第11行是一个空行,没有body消息。

一个http请求包括三个部分:

  1. 请求行
  2. 请求头
  3. 消息体(body)[可选]

2.1 请求行

GET /hello HTTP/1.1

包括三个部分:

  1. 请求方法,这里是GET
  2. 访问资源url,这里是/hello
  3. http版本,这里是1.1

上面的请求行,简单理解就是:采用http 1.1协议,向/hello发送一个GET请求,希望获取到该url对应的资源。

这里,我们要重点了解下请求方法。有过开发经验,尤其是restful api接口开发经验的朋友,应该比较了解常用的请求方法。比如:GET、POST、PUT、DELETE等。

  • 关于restful api接口的规范和实践使用,会在后续文章中具体介绍

2.1.1 请求方法(9种)

  • GET - 可以理解为查询行为,获取指定的资源,一般用来获取数据。
  • POST - 可以理解为新增行为。服务端会根据请求的内容,在服务器上创建相应的资源。
  • PUT - 可以理解为修改行为。服务端会根据请求的内容,如果对应的URI存在,则进行修改。如果不存在,则进行创建。(可选)
  • DELETE - 可以理解为删除行为。服务端会删除对应的URI资源。
上述四种方法,是在做后端开发中会经常用到的。我们常说的“CRUD-增删改查”,就可以简单一一对应到相应的方法上。
  • HEAD - 该方法和GET类似,只是服务器仅返回http状态行和头部信息,不会返回body内容。可以用于只需要获取相应资源meta信息,而不需要获取整个资源内容。
Tip:该方法可在实践中用于“服务探活”或者用于心跳机制中的”心跳包“。
  • OPTIONS - 该方法可以返回针对特定URI所支持的http方法。常用于检查web服务针对特定资源所提供的功能。后续我们还会提到它,用于解决前端跨域问题。
  • CONNECT - 该方法用于将请求转换为透明的tcp/ip隧道。常用于HTTPS。
  • PATCH - 该方法可用于更新特定资源的部分内容。相对很少使用。
  • TRACE - 该方法使服务器原样返回任意客户端请求的任何内容。主要用于协议调试。存在安全问题,建议服务端关闭,不要使用。
2.1.1.1 方法特性 - 安全性

某些方法在设计时就被定义为"安全方法"。所谓的安全方法是指用于检索数据,不会改变服务资源的状态。专业点的说法就是不会产生”副作用“(side effects)。比如:get方法不会改变资源的内容,是安全的,而delete方法会删除特定的资源,是不安全的。

2.1.1.2 方法特性 - 幂等性

某些方法在设计时就被定义为幂等的。所谓幂等是指相同的请求,无论调用多少次,都会产生一样的作用。比如:DELETE。对于任一个DELETE请求,无论执行多少次,其产生的作用是一样的。也就是说删除某个特定资源一次,和删除多次,其对资源的作用是一样的。

Tip:要注意区分安全性和幂等性的区别。安全性是强调不会产生副作用,而幂等性强调的是多次请求所产生的作用是一样的。
2.1.1.3 方法小结
来自维基百科的表格,略作调整
方法名RFC文档Request has BodyResponse has Body安全幂等可缓存
GETRFC 7231OptionalYesYesYesYes
POSTRFC 7231YesYesNoNoYes
PUTRFC 7231YesYesNoYesNo
DELETERFC 7231NoYesNoYesNo
HEADRFC 7231NoNoYesYesYes
OPTIONSRFC 7231OptionalYesYesYesNo
CONNECTRFC 7231YesYesNoNoNo
PATCHRFC 5789YesYesNoNoNo
TRACERFC 7231NoYesYesYesNo
注意:POST方法不是幂等的。在接口开发时,要处理可能会出现的幂等问题。关于接口幂等问题的处理,可以参考后续的文章。PUT和DELETE方法是幂等的,GET也是。

2.1.2 访问资源

/hello,为该GET请求的资源地址。和头部区域中的HOST部分一起确定唯一的资源地址。

2.1.3 协议版本号

HTTP/1.1 - 表明使用的http协议版本是1.1

2.2 请求头

请求头位于请求行之后,使用key-value的格式,并以CRLF结尾。也就是说每行都是一个键值对。请求头可以包括多个键值对。最后使用一个空行,来表明整个请求头的结束。

标准请求头字段有36个,非标准的有十多个。作为后端开发人员,需要了解一些常见的请求头。我们首先介绍下'hello,world'中的请求头,后续出现其它的请求头字段时再一一说明。

注意:请求头字段名是大小写不敏感的,而方法名都是大写的,是大小写敏感的。

2.2.1 "hello, world" 请求头

字段描述例子备注
Host主机地址,包括域名和端口号。(用于支持虚拟主机)Host: localhost:9800HTTP/1.1是强制必须要有的。HTTP/2 将不使用该字段。
Connection当前连接控制选项Connection: keep-aliveHTTP/1.1默认是keep-alive。HTTP/2 将不使用该字段。
User-Agenthttp客户端名称User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/69.0.3497.100 Safari/537.36
服务端可根据此字段了解客户端的类型。常用于访问统计。
Accept可接受的响应内容媒体格式text/html,application/xhtml+xml,application/xml;
q=0.9,image/webp,image/apng,/;q=0.8
Accept-Language可接受的语言Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Accept-Encoding可接受的数据压缩编码格式Accept-Encoding: gzip, deflate, br可用于提升数据传输性能
Pragma特殊指令,常用于进行缓存控制Pragma: no-cache支持HTTP/1.0,HTTP/1.1
Cache-Control缓存控制指令Cache-Control: no-cache支持HTTP/1.1
Upgrade-Insecure-Requests告诉服务端,建议从http升级到https。常用于过度阶段。Upgrade-Insecure-Requests: 1非标准字段

Tip:

  • 关于Connection的keep-alive,详见后续文章。

2.3 消息体-body部分

该GET请求中,消息体部分为空。后续出现具有body部分的请求时,我们会具体分析。

3. 小结

本节我们主要介绍了http协议请求部分的基本内容。当然这只是http协议的一部分,也是作为web后端开发人员需要掌握的基本知识。在后面的文章中,会逐渐展开http协议的相关内容。希望通过具体项目开发实践和所使用的技术背后的知识相结合,能够给大家带来帮助。下一节,我们将分析http响应相关的内容。

本文为作者原创作品,属于《重新学习web后端开发》专辑中的一篇,转载时请备注作者信息及来源。本文原文地址:https://www.donnyzhang.com/20...

相关推荐