🤔 HTTP常见问题
1. TCP/IP 协议
计算机与网络设备要相互通信,双方就必须基于相同的方法。如何探测到通信目标,由哪一边先发起通信、使用哪种语言进行通信,怎样结束通信等规则都需要事先确定。我们把这种规则成为协议 (protocol)。与互联网相关联的协议集合起来总称为 TCP/IP。
TCP/IP 各层的作用
应用层:决定了向用户提供应用服务时通信的活动。如 FTP (file transfer protocol, 文本传输协议),DNS (domain name system 域名系统), HTTP
传输层:TCP 和 UDP
网络层:用来处理在网络上流动的数据包。该层规定了通过怎样的路径(传输路线)到达对方计算机,并将数据包传送给对方。
链路层:连接网络的硬件部分。IP 协议
负责传输。IP 协议确保数据包传给了对方。IP 地址指明了节点被分配到的地址;传输过程中,使用 ARP 协议获取 MAC 地址进行中转。TCP
确保可靠性。TCP 协议对大块数据分割成以报文段为单位的数据包进行管理,并确认数据最终送达到对方。TCP 采用三次握手策略。发送端首先发送一个带 SYN 标志的数据包给对方。接收端收到后,回传一个带有 SYN?ACK 标志的数据包以示传达确认。最后,发送端再回传一个带 ACK 标志的数据包,代表“握手”结束。DNS
DNS 提供域名到 IP 地址之间的解析服务。
- URL
URL(Uniform Resource Locator, 统一资源定位符),是 web 浏览器访问页面时需要输入的地址。
- URI
URI(Uniform Resource Identifier, 统一资源标识符),是由某个协议方案(http, ftp, mailto, telnet, file 等)表示的资源的定位标识符。
1 | // URI组成依次为协议方案名,登录信息,服务器地址,服务器端口,带层次的文件路径,查询字符串,片段标识符 |
2. HTTP报文
请求从客户端发出,最后服务器端响应该请求并返回。HTTP是一种不保存状态,即无状态协议。
用于 HTTP 协议交互的信息被称为 HTTP 报文。HTTP 报文本身是由多行数据构成的字符串文本。
2.1 请求首部字段
Connection
HTTP的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。每次请求都会造成无谓的TCP连接建立和断开,增加通信量的开销。为了解决这个问题,HTTP/1.0想到了持久连接Keep-alive。只要任意一端没有明确提出断开连接,则保持TCP连接状态。在HTTP/1.1中,所有的连接默认都是持久连接。1
2
3
4
5
6# HTTP/1.1前的默认连接都是非持久链接,如果想维持持续链接,需要指定Keep-Alive
Connection: Keep-Alive
# 服务器想明确断开连接时,则指定为 close
Connection: CloseCache-Control
操作缓存的工作机制
缓存请求指令 | |
---|---|
no-cache | 客户端将不会接收缓存过的响应 |
no-store | 不能在本地存储请求或响应的任一部分 |
max-age | 缓存资源的缓存时间比max-age小,就接受缓存的资源 |
min-fresh | 期望在指定时间内的响应仍有效 |
max-state | 即使过期,只要仍处于max-state指定时间内,仍会被客户端接收 |
only-if-cached | 要求缓存服务器不重新加载响应,也不再次确认资源有效性。若缓存服务器无反应,则返回504 Gateway Timeout |
no-transform | 缓存不能改变实体主题的媒体类型,防止缓存或代理压缩图片等操作 |
缓存响应指令 | |
---|---|
public | 表明其他用户也可以利用缓存 |
private | 只对特定用户提供资源缓存的服务 |
no-cache | 原服务器不对缓存服务器请求中提出的资源有效性进行确认,且禁止其对相应资源进行缓存操作 |
no-store | 不能在本地存储请求或响应的任一部分 |
s-maxage | 资源保存为缓存的最长时间 |
must-revalidate | 代理会向源服务器再次验证即将返回的响应缓存目前是否有效 |
proxy-revalidate | 缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性 |
no-transform | 缓存不能改变实体主题的媒体类型,防止缓存或代理压缩图片等操作 |
- Content-Type
常见的媒体资源:- text/html: HTML 格式
- text/plain: 纯文本格式
- text/xml: XML 格式
- 图片格式:image/gif, image/jpeg, image/png
- application/json: JSON 数据格式
- application/x-www-form-urlencoded: form 表单数据被编码为 key/value 格式发送到服务器(表单默认的提交数据的格式)
- multipart/form-data:在表单中进行文件上传时,会使用该格式
Content-Range
范围请求,允许你实现从之前下载中断处恢复下载Accept
通知服务器,用户代理能够处理的媒体类型及媒体类型
2.2 响应首部字段
- Set-Cookie
服务端发送的响应报文内的一个叫做 Set-cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
2.3 其他
- Date
表明创建 HTTP 报文的日期和时间 - Transfer-Encoding
规定传输报文主体时采用的编码方式 - Upgrade
检测是否可以使用更高的协议版本进行通信 - Via
追踪客户端与服务器之间的请求和响应报文的传输路径 - Authorization
用户代理的认证信息 - Host
表示请求的资源所处的互联网主机名和端口号 - If-Match:”123456”
告知服务器匹配资源所用的实体标记 (ETag 值) - If-Modified-Since:
在日期时间之后,如果请求的资源没有更新过,则返回状态码 304 Not Modified - Referrer
请求的 URI 是从哪个 web 页面发起的 - User-Agent
创建请求的浏览器和用户代理名称
3. 请求方法
HTTP方法 | |
---|---|
GET | GET请求会显示请求指定的资源。一般来说GET方法应该只用于数据的读取,而不应当用于会产生副作用的非幂等的操作中。它期望的应该是而且应该是安全的和幂等的。这里的安全指的是,请求不会影响到资源的状态。 |
POST | 传输实体主题 |
PUT | 传输文件 |
HEAD | 获得报文首部,用于确认URIDE有效性及资源更新的日期时间 |
DELETE | 删除文件 |
OPTIONS | 询问支持的方法 |
TRACE | 请求连接到源目标会通过代理中转,trace方法用来确认连接过程中发生的一系列操作 |
CONNECT | 要求用隧道协议连接代理 |
4. 状态码
- 1XX Informational(请求正在处理)
- 2XX Success(请求成功)
- 3XX Redirection(重定向) 需要进行附加操作以完成请求
- 4XX Client Error(客户端错误)
- 5XX Server Error(服务器错误)
状态码 | 描述 |
---|---|
100 Continue |
临时响应,表明客户端应该继续请求 |
101 Switching Protocol |
服务器正在切换协议 |
102 Processing (WebDAV) |
服务器已收到并正在处理,但没有响应可用。 |
2XX 表示成功处理了请求的状态代码。 | |
200 OK |
服务器已成功处理了请求。 |
201 Created |
请求成功并且服务器创建了新的资源,通常是PUT请求后的响应。 |
202 Accepted |
服务器已接受请求,但尚未处理。 |
203 Non-Authoritative Information |
服务器已成功处理了请求,但返回的信息可能来自另一来源。 |
204 No Content |
服务器成功处理了请求,但没有返回任何内容。 |
205 Reset Content |
服务器成功处理了请求,但没有返回任何内容。 |
206 Partial Content |
服务器成功处理了部分 GET 请求。 |
3开头,请求被重定向,表示要完成请求,需要进一步操作。 | |
300 Multiple Choice |
服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。 |
301 Moved Permanently |
请求的网页已永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。 |
302 Found |
服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 |
303 See Other |
请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。 |
304 Not Modified |
上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。 |
307 Temporary Redirect |
服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 |
4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。 | |
400 Bad Request |
服务器不理解请求的语法。 |
401 Unauthorized |
请求要求身份验证 |
403 Forbidden |
服务器拒绝请求。 |
404 Not Found |
服务器找不到请求的网页。 |
405 Method Not Allowed |
禁用请求中指定的方法。 |
406 Not Acceptable |
无法使用请求的内容特性响应请求的网页。 |
407 Proxy Authentication Required |
此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。 |
408 Request Timeout |
服务器等候请求时发生超时。 |
409 Conflict |
由于和被请求的资源的当前状态之间存在冲突,请求无法完成。 |
410 Gone |
被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址。 |
411 Length Required |
服务器拒绝在没有定义 Content-Length 头的情况下接受请求。 |
412 Precondition Failed |
服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。 |
413 Payload Too Large |
服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。 |
414 URI Too Long |
请求的 URI(通常为网址)过长,服务器无法处理。 |
415 Unsupported Media Type |
请求中提交的实体并不是服务器中所支持的格式,请求被拒绝 |
416 Requested Range Not Satisfiable |
请求中包含了 Range 请求头,并且 Range 中指定的任何数据范围都与当前资源的可用范围不重合,同时请求中又没有定义 If-Range 请求头 |
417 Expectation Failed |
服务器未满足”期望”请求标头字段的要求。 |
5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。 | |
500 Internal Server Error |
服务器遇到了不知道如何处理的情况。 |
501 Not Implemented |
此请求方法不被服务器支持且无法被处理。 |
502 Bad Gateway |
此错误响应表明服务器作为网关需要得到一个处理这个请求的响应,但是得到一个错误的响应。 |
503 Service Unavailable |
服务器没有准备好处理请求。 常见原因是服务器因维护或重载而停机。 |
504 Gateway Timeout |
当服务器作为网关,不能及时得到响应时返回此错误代码。 |
505 HTTP Version Not Supported |
服务器不支持请求中所用的 HTTP 协议版本。 |
5. Web服务器
HTTP/1.1允许一台HTTP服务器搭建多个Web站点。即使物理层面只有一台服务器,但只要使用虚拟主机的功能,则可以假象已具有多台服务器。域名通过DNS服务映射到IP地址,当请求发送到服务器时,已经是以IP形式访问了。
由于虚拟主机可以寄存多个不同域名的web网站,因此在发送http请求时,必须在Host首部完整指定域名的URI。
5.1 代理、网关、隧道
HTTP通信时,除了客户端和服务器意外,还有一些用于通信数据转发的应用程序。它们将请求转发给通信线路上的下一站服务器,或者将服务器发送的响应转发给客户端。
代理
作用:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的。
缓存代理:代理转发响应时,缓存代理会预先将资源的副本保存在代理服务器上。当代理再次接收到相同资源请求时,可以不从服务器那里获取,而是将之前缓存的资源作为响应返回。
透明代理:转发请求或响应时,不对报文做任何加工的代理。
网关
网关能使通信线路上的服务器提供非HTTP协议服务。利用网关可以提高通信的安全性,在通信线路上加密;网关可以连接数据库,使用sql语句查询数据。
隧道
隧道可按要求建立起一条与其他服务器的通信线路,使用SSL等加密手段进行通信。确保客户端能与服务器进行安全的通信。
5.2 缓存
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。
客户端的缓存
存在于客户端浏览器中的文件,成为临时网络文件(Temporary Internet File)。浏览器缓存如果有效,可以直接从本地磁盘内读取。
缓存的有效期限
即使存在缓存,也会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失效,缓存服务器将再次从源服务器上获取新资源。
缓存可以简单分为两种类型:强缓存(200 from cache) 与协商缓存(304)。对于协商缓存,使用ctrl + F5强制刷新可以使得缓存无效。但是对于强缓存,在未过期时,必须更新资源路径才能发起新的请求(更改路径相当于是另一个资源)。
强缓存(200 from cache)
浏览器如果判断本地缓存未过期,就直接使用,无需发起http请求1
2
3
4 属于强缓存
(http1.1)Cache-Control/Max-Age
(http1.0)Pragma/Expires
`
协商缓存(304)
浏览器会向服务端发起 http 请求,然后服务端告诉浏览器文件未改变,让浏览器使用本地缓存
1 | 属于协商缓存 |
6. 常见问题
6.1 CDN原理
当我们在地址栏输入一个网址,浏览器发现本地没有关于这个网址的 DNS 缓存,所以向网站的 DNS 服务器发起请求。
网站的 DNS 服务器设置了 CNAME,指向了某个 CDN 服务器,也就是我们常见的阿里云、腾讯云。
如果是第一次访问该内容,CDN 服务器会向源站请求数据并缓存。
否则,CDN服务器会找到 缓存了这个资源,并对用户响应最快的节点返回给用户,然后用户向该节点发出请求。
6.2 shadowsock原理
在很久很久以前,我们访问各种网站都是简单而直接的,用户的请求通过互联网发送到服务提供方,服务提供方直接将信息反馈给用户。
然后有一天,GFW 就出现了,他像一面墙,每当用户需要获取信息,都经过了 GFW,GFW 将它不喜欢的内容统统过滤掉,于是客户当触发 GFW 的过滤规则的时候,就会收到 Connection Reset 这样的响应内容,而无法接收到正常的内容。
聪明的人们想到了利用境外服务器代理的方法来绕过 GFW 的过滤,其中包含了各种 HTTP 代理服务、Socks 服务、××× 服务… 其中以 ssh tunnel 的方法比较有代表性
- 首先用户和境外服务器基于 ssh 建立起一条加密的通道
- 用户通过建立起的隧道进行代理,通过 ssh server 向真实的服务发起请求
- 服务通过 ssh server,再通过创建好的隧道返回给用户
6.3 Https
HTTP协议,本身是明文传输的,因此很容易在传输过程中被中间这窃听、篡改、冒充。(Wifi热点,路由器,防火墙,反向代理,缓存服务器)。为了解决这些风险,HTTPS的价值就体现出来了
- 内容加密,第三方无法窃听。
- 身份认证,一旦被篡改,通信双方会立刻发现。
- 数据完整性。防止内容冒充或者篡改。
HTTPS,即HTTP下加入SSL层。HTTP + SSL/TLS。HTTPS的整个交互过程如下:
- 用户在浏览器里输入一个https网址,此时客户端发起https请求,通过tcp和服务器建立连接(433端口)。
- 服务器存放CA证书进行处理,注意用HTTPS的服务器必须要有一套数字证书,这套证书其实一对公钥和私钥。
- 服务器向客户端返回证书。证书包含:域名,申请证书的公司,公钥。
- 客户端对证书进行解析。这个工作由客户端的TLS完成,首先会验证公钥是否有效,如颁发机构,过期时间等。如果发现异常,就会弹出一个警告框,提示证书存在问题。如果证书没有问题,就会生成一个随机数,然后用证书对该随机数进行加密。
- 向服务器发送证书加密后的随机数
- 服务器用它的私密进行解密,得到客户端传来的随机数
- 服务器用客户端的随机数加密后的信息发送给客户端
- 客户端用之前生成的私钥解密服务端传过来的信息
6.4 自定义HTTP请求方法?
不能。
HTTP1.0定义了三种请求方法: GET、POST、HEAD
HTTP1.1新增了五种请求方法:OPTIONS、PUT、DELETE、TRACE 、CONNECT
6.5 多个域名加载资源
Q: 为什么同一网站的资源要使用不同域名加载(oss,cdn)
A: 浏览器对同一有连接数的限制。
6,6 TCP, UDP, IP, HTTP的区别
TCP, UDP是传输层协议,IP是网络层协议,HTTP是应用层协议。
- IP
是用来找到目标计算机。如A向B发送数据,那么要找到对方B的计算机,找到后就确定了网络间的通道,A - B。也就是说IP是来确定网络间的路径的。 - TCP
是用来实现通信的,在IP实现了网络间路径后,TCP提供了这个路径的全双工通信的能力。这个链接的建立要经历三次握手,断开链接要四次挥手。(全双工:A可以给B发送数据的同时,B也可以给A发送数据) - UDP
是和TCP相似的,也是提供了通信能力。不过和TCP有区别。TCP是点对点的通讯,UDP支持一对多,多对一,一对一等。UDP不需要链接,直接发数据,相对来说速度更快,但是不保证数据一定会到达,适合广播。 - HTTP
http是应用层的协议,它实现了怎么发数据和怎么收数据,定义了收发的格式
6.7.HTTP 2.0
延迟
影响一个 HTTP 网络请求的因素主要有两个:带宽和延迟。
- 浏览器阻塞
浏览器对于同一个域名有连接数限制。超过浏览器最大连接数限制,后续请求就会被阻塞。 - DNS 查询
浏览器需要知道目标服务器的 IP 才能建立连接。利用 DNS 缓存可以减少这个时间 - 建立连接
HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。
HTTP1.0和HTTP1.1的区别
- 缓存处理
HTTP1.0中使用If-Modified-Since,Expires来做缓存判断的标准。HTTP1.1则引入了更多缓存控制策略,如Entity tag,If-Unmodified-Since, If-Match, If-None-Match。 - Range
允许只请求资源的某个部分,支持断点续传功能 - Host
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域。 - 长连接
HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive - 新增24个错误状态响应码
HTTP1.0和1.1存在的问题
- 明文传输
- 请求头内容过大,每次请求header基本不怎么变化,增加了传输成本
- 虽然HTTP1.x支持了keep-alive,来弥补多次创建连接产生的延迟,但是keep-alive使用多了同样会给服务端带来大量的性能压力,并且对于单个文件被不断请求的服务(例如图片存放网站),keep-alive可能会极大的影响性能,因为它在文件被请求之后还保持了不必要的连接很长时间
HTTP2.0新特性
- 二进制格式
HTTP1.X的解析是基于文本,二进制则只认0和1的组合,方便且健壮。 - 多路复用
连接共享。一个request对应一个id,这样一个连接上可以有多个request,request可以随机的混杂在一起,接收方可以根据request的id将request再归属到各自不同的服务端请求里。某个请求耗时严重,不会影响其他请求的正常执行。 - header压缩
通讯双方各自cache一份header fields表,避免了重复header的传输,又减少了传输的大小 - 服务端推送
服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。
6.8 大文件分片上传
6.9 无痕模式
从功能上明确无痕浏览的作用,涉及的功能包括:Bookmark, History(input, browser, download, forms/auto complete), SSL certs, Cookie, local storage, webSQL, Application cache, HTTP Cache, Disk Cache, Web App/Plugin。
从正常模式进入无痕模式
进入无痕模式前的信息是否会在无痕下使用再次进入无痕模式
在前一无痕模式下设置的项目,是否可以在下一次无痕模式下使用
6.10. 多路复用 vs 长连接
HTTP2.0多路复用和HTTP1.X中的长连接复用有什么区别?
- HTTP/1.*
一次请求-相应,建立一个连接,用完关闭;每一个请求都要建立一个连接 - HTTP/1.1 Pipeling
若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞。 - HTTP/2
多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其他连接的正常执行。
6.11. 三次握手 & 四次挥手
三次握手
- 第一次握手:客户端给服务器发送一个 SYN 报文。客户端处于 SYN_send 状态。
- 第二次握手:服务器收到 SYN 报文之后,会应答一个 SYN+ACK 报文。服务器处于 SVN_REVD 状态。
- 第三次握手:客户端收到 SYN+ACK 报文之后,会回应一个 ACK 报文。客户端处于 establised 状态。
- 服务器收到 ACK 报文之后,三次握手建立完成。服务器处于 establised 状态。
三次握手的作用
- 为了确认双方的接收和发送能力是否正常。
- 指定自己的初始化序列号,为后面的可靠传送做准备。
- 如果是 https 协议的话,三次握手这个过程,还会进行数字证书的验证以及加密密钥的生成。
四次挥手
- 第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态。
- 第二次握手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT状态。
- 第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
- 第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态
- 服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
6.12 https抓包原理
为什么用了https还能被抓包?
Charles作为一个中间人代理,当浏览器和服务器通信时,Charles接收服务器的证书,但是不会发给浏览器,而是动态生成一张证书发送给浏览器。由于Charles更改了证书,浏览器校验不同过会弹出安全警告,所以必须安装Charles的证书后才能正常访问。
Charles需要做的事情是对客户端伪装服务端,对服务端伪装客户端:
- 截获真实客户端的https请求,伪装客户端向真实服务端发送https请求。
- 接受真实服务器响应,用charles自己的证书伪装服务端向真实客户端发送数据内容。
6.13 URL长度限制
2083字节(2kb + 53)
6.14 端口上限
65535(2^16-1)