面向新手的HTTP介绍
下文全文复制自markdown渲染结果,如果有什么bug的话……那我也没办法咯。
参考文献:rfc2616,rfc7540以及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,而消息体为空的消息则不通常带有此类头。
- 关于Transfer-Encoding的内容请详见MDN: Transfer-Encoding。
此外,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是可以共存的说。
以上。
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!
- 来自作者
- 相关推荐