qwerty
qwerty

除特殊说明外,本账号所有原创作品依cc-by-nc-sa 3.0或更高版本开放授权。

面向新手的HTTP介绍

下文全文复制自markdown渲染结果,如果有什么bug的话……那我也没办法咯。


参考文献:rfc2616rfc7540以及MDN web文档

如有任何出入,请以rfc为准,其次以mdn文档为准。

下文越1000字,虽然链接比较多,不过建议都看一看。

Hypertext transfer protocol

HTTP,aka“超文本传输协议”,是浏览器与服务器之间的通信所使用的通信协议。在浏览器中输入网址之后,页面就是通过HTTP协议被传输过来的。

HTTP的消息分为两种,请求和响应。下面是一个 简单的HTTP请求:

GET / HTTP/1.1
Host: example.com
Connection: close

而下面是一个简单的响应(不是对上面这个东西的响应)

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 8

response

可以看到,HTTP消息由三部分组成,首行,消息头和消息体。消息头和消息体均可以为空。无论消息头或消息体是否为空,消息头均以一个空行结束。

另外需要注意的是,HTTP协议所使用的换行一律是CRLF,或者说\r\n。

首行

HTTP请求的首行有两种,分别为请求所使用的请求行,例如

GET / HTTP/1.1

请求行由三部分组成,分别是方法(GET),URI(/)和http版本(HTTP/1.1),三部分由空格分隔开。

响应所使用的状态行,例如

HTTP/1.1 200 OK

也由三部分组成,分别是http版本(HTTP/1.1),状态码(200)和原因说明短语(OK)。

因为此处讨论的是http 1.1版,所以此处使用的版本号均为http/1.1。

关于方法,URI和状态码的详细讨论请见下文(或rfc)。

消息头

消息头的每一行均为以冒号分隔的键值对,不同的键具有不同的功能,例如

Host: example.com

此处的Host头用于指定所请求的域名。按规定所以有的HTTP/1.1请求都必须指定host。(嗯,按规定)。

不同的消息会有一些特定的消息头,比如Host头就是HTTP请求专用的。另一个例子是,带有消息体的消息都必须要么指定Content-Length,要么指定Transfer-Encoding: chunked,而消息体为空的消息则不通常带有此类头。

此外,Content-Type头对于带有消息体的消息来说也是非常重要的,这个字段关系到消息的接收方会以什么方式处理消息。Content-Type中所指定的类型以mime类型(rfc6838)为标准。例如,如果希望浏览器把接收到的消息体当作html渲染出来,那么Content-Type就应该指定为text/html。(这个字段很重要呢,对于请求来说也很重要呢)

消息体

消息体可以说是消息的本体啦。比如,在请求一个页面时,页面本身的内容就是在响应体中携带的。HTTP请求也可以携带请求体,这种请求通常会被配置为由http服务器转发给web应用服务器(aka web后端)进行处理。(嘛不过这种东西大概只有自己做过才会知道是什么样的吧)。

方法

HTTP协议定义了多种不同的方法,而这些方法是“具有语义”的。具体有什么方法,每个方法是什么样子的,这里还是比较推荐去看rfc啦。不过同样推荐这个tldr版本

再简单得复习一下:

  • GET方法作为最常用的方法,是用来获取资源的。GET请求“依语义不应该”携带请求体。HTTP服务器“不应该”因为某个GET请求而执行会造成状态改变/副作用的动作。GET请求的响应默认是会被缓存的,因此默认情况下并不是每个GET请求最终都会到达HTTP服务器。
  • POST方法按语义用于“提交/新增”资源。重复多次进行POST请求可能会让这种副作用重复多次发生。
  • PUT方法用于“替换”资源。即使同一个PUT请求多次发生,其产生的副作用应该与进行过一次请求时相同。
  • PATCH方法用于“部分修改”资源。与POST类似,多次重复请求可能会使这种副作用重复发生。

注意:对PUT的这种称为“幂等性”的要求依赖于后端实现,因此对于PUT是否真的幂等请以对方/同事的书面回复为准。

状态码

响应首行的状态码用于描述响应的各种状态。2xx为响应成功,3xx为重定向,4xx为客户端错误,5xx为服务器错误。

其中最常见的有,200 OK,301永久重定向,302临时重定向,403禁止,404找不到,500服务器内部错误,503不可用,504网关超时等,此外还有与缓存控制相关的“304未修改”等。

这里有一个比较完整的状态码列表。

关于XHR

XHR,XMLHttpRequest,或者ajax技术,是在浏览器端使用javascript动态发起http请求的技术。XHR可以用于无刷新得更新页面,这种应用被称为局部刷新。

在web application中,大多数客户端-服务器通信都是使用XHR来完成的。

出于安全性考虑,浏览器会将XHR限制为“只能请求相同来源的资源”。这种限制称为“同源策略”。

关于“同源策略”

同源策略是浏览器出于安全性考虑所做出的一系列限制。同源策略可以阻止大部分通过浏览器的跨网站的恶意访问。因为浏览器上会有多种多样来自不同来源的网站和web app,因此同源策略对于web安全至关重要。

同源策略不会做什么

同源策略无法阻止浏览器之外的恶意访问。同源策略是由浏览器保证的。但你不能假设你所接收到的请求一定来自于浏览器。

同源策略不会阻止用户有意进行的恶意访问。用户可以出于故意绕过同源策略,浏览器不会阻止用户故意发起的请求。

同源策略不会阻止非恶意的访问。例如,跨域的静态资源共享是被允许的。如果网站设置了CORS头,那么跨域请求是被允许的。

关于HTTP/2和HTTP/3

HTTP/2和HTTP/1.1具有很大不同,HTTP/2的消息不再是基于文本的,因此具有更低的开销。同时,HTTP/2允许在同一个链接内同时进行多个请求,配合TLS的某些改进,HTTP/2可以大幅度减少传输所需要时间。

另外,HTTP/2引入了一些新功能,比如服务器推送,可以用于由服务器主动向客户端发送消息。

虽然HTTP/2并不要求TLS,但是主流的浏览器和服务器都要求HTTP/2运行于TLS之上。

  • TLS是什么?就是HTTPS后面那个S啦,关于如何配置TLS……emmm……不如去看一看letsencrypt怎么说啦。

HTTP/3最初为“http/2 over quic”,既使用新的传输层协议quic来进一步改进http/2。目前依然在开发中。

  • 不过quic目前使用UDP端口,反正TCP 443和UDP 443是可以共存的说。

以上。

CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…
加载中…

发布评论