FE.BASE-HTTP基础梳理

前言

本文梳理本人阅读《HTTP权威指南》遇到的相关问题与相关解答。若有错误请指正。

OSI参考模型

应用层,表示层,会话层,传输层,网络层,数据链路层,物理层

URL

<方案>://<用户>:<密码>@<主机>:<端口>/<路径>;<参数>?<查询>#<片段>

如果<标签>内有保留受限字符(比如密码有@),这些可通过encodeURIComponent转义。
DNS解析过程详解

状态码

HTTP状态码

重定向302、303、307的区分

【1】HTTP1.0(RFC1945)和HTTP1.1(RFC2616)对302的定义相同:如果客户端发出POST请求后,收到服务端的302状态码,那么不能自动的向新的URI发送重复请求,必须跟用户确认是否该重发,因为第二次POST时,环境可能已经发生变化(POST方法不是幂等的),POST操作会不符合用户预期。

【2】303和307是HTTP1.1新加的,是对原302状态码的细化。HTTP1.1规定303处理应是:POST重定向为GET,307处理应该是:POST重定向为POST(不一定是POST,非GET、HEAD请求即可)303和307的存在,归根结底是由于POST方法的非幂等属性引起的。

【3】但是浏览器实现HTTP1.0的302二次请求POST时未询问用户的情况下就变成GET(相当于303)

参考资料 HTTP状态码302、303和307的故事

HTTP报文

HTTP报文组成(部分):

- 起始行
 - 请求起始行:方法 URL HTTP版本
 - 响应起始行:HTTP版本 状态码 原因短语
- 首部
 - 通用首部: Date:Tue, 3 Oct 1974 02:16:00 GMT
   通用缓存首部:  Cache-Control
 - 请求首部: Accept:*/*
            From
            Host
            Referer
            User-Agent
   条件请求首部: If-Modified-Since
                If-Match
   安全请求首部: Cookie
               Authorization
            ...
 - 响应首部: Server:cloudflare-nginx
 - 实体首部: Content-Type:text/html;charset-iso-latin-1
    内容首部: Content-Length
    实体缓存首部:ETag
                Expires:Fri, 01 Mar 2019 13:37:39 GMT
                Cache-Control:max-age=600
                Last-Modified:在服务器最后被修改的时间
 - 扩展首部
- 主体

ETag、Expires、Last-Modified解析

根据是否需要向服务器重新发起HTTP请求将缓存过程分为两个部分,分别是强制缓存协商缓存

强制缓存

有3种:
1.不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求
2.存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存
3.存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果

控制强制缓存的字段分别是Expires和Cache-Control。到了HTTP/1.1,Expire已经被Cache-Control替代,原因在于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,那么如果客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确)发生误差。所以同时存在时,只有Cache-Control生效

浏览器的缓存存放在哪:
内存缓存(from memory cache):js和图片等
硬盘缓存(from disk cache):css文件

协商缓存

有2种:
1.协商缓存生效,返回304
2.协商缓存失效,返回200和请求结果
控制协商缓存的字段分别有:
Last-Modified / If-Modified-Since
服务端返回last-modified即最后修改时间,客户端下次发送if-modified-since(时间)后服务器比对。
Etag / If-None-Match
服务端返回Etag即唯一标识,客户段下次发送If-None-Match(标识)后服务器比对。

其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。

缓存优先级递减次序

no-store;(禁止保存临时文件,保护机密信息)
no-cache;(1.0的键名是Pragma,1.1是Cache-Control;在释放缓存之前,强制高速缓存将请求原始服务器验证。)
must-revalidate;(缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。)
max-age;(相对秒)
expries;(绝对日期时间)
参考:Cache-Control-MDN

承载TCP段的IP分组

TCP收到HTTP报文数据流后分段成IP分组,IP分组包括:
IP分组首部(20B)+TCP段首部(20B)+TCP数据块(0+B)
《FE.BASE-HTTP基础梳理》

Nagle和TCP_NODELAY

Nagle算法鼓励发送最大传输单元(MTU:1500B),但确认分组延迟确认要等100-200ms。(为什么MTU值普遍都是1500?)
TCP_NODELAY方法即可禁用Nagle(nodejs默认开启)

socket.setNoDelay([noDelay])
request.setNoDelay([noDelay])

MSL和TIME_WAIT

MSL(最大分段生存期)指明TCP报文在Internet上最长生存时间,每个具体的TCP实现都必须选择一个确定的MSL值。RFC1122建议是2分钟。超过该数值会有TIME_WAIT累积与端口耗尽问题。

持久链接&管道化链接

HTTP/1.0+"Connection:keep-alive"节省了打开链接和关闭链接的开销。
HTTP/1.1持久链接默认激活(前提:主体部分长度与Content-Length一致或分块传输编码),除非客户端发送报文有Connection:close。
HTTP/1.1允许在持久链接上使用请求管道,在响应到达之前可将多条请求放入队列,降低网络环回时间。(客户端不应在管道上发送POST这样非幂等请求,因为出错无法安全重试)

网关&隧道&中继

协议网关负责将一个协议转成另一个协议,常见的有HTTP/FTP、HTTP/HTTPS、HTTPS/HTTP。

资源网关负责HTTP请求与服务端应用转换,最流行的协议是CGI(输入请求,转交,响应),为避免每条CGI请求新开进程,出现了FastCGI作为持久守护进程。

隧道负责让HTTP应用访问非HTTP协议的程序。通过CONNECT方法请求隧道网关创建一条到达任意目的服务器端口的TCP链接,并对客户端和服务器之间的后续中继数据进行盲转发。

中继负责处理HTTP中建立连接的部分,然后对字节进行盲转发。

web爬虫

拒绝爬虫方法1:域名更目录放robots.txt,爬虫会根据它做选择。

# this robots.txt allows Slurp & Webcrawler to crawl

User-Agent: slurp
User-Agent: webcrawler
Disallow: /private
Allow: /public

User-Agent: *
Disallow:

拒绝爬虫方法2:robot-control标签
index|follow|noarchive|all|none

<meta name="robots" content="noindex">

SSL和HTTPS

对称秘钥加密即编解码使用相同秘钥,如DES,3-DES,RC2,RC-4。缺点是发送者和接收者对话前要存有该秘钥。

公开秘钥加密使用非对称秘钥:客户端持公开秘钥,服务端持私有秘钥。避免了上述对称秘钥的缺点。如RSA。

对报文使用非对称秘钥数字签名,可以证明作者和防止篡改。

数字证书结构:版本号,序列号,签名算法,颁发者,有效期,对象名称,公开秘钥,其他扩展信息,数字签名。

OpenSSL是SSL和TLS协议以及一个全功能通用加密库的开源实现。

SSL握手需要做的工作:
交换协议版本号;选择一个两端都了解的密码;对两端的身份进行认证;生成临时会话秘钥,以便加密信道。

SSL握手过程:
1.客户端发送可选择的密码并请求证书
2.服务器发送选中的密码和证书
3.客户端发送保密信息,客户端和服务器生成秘钥。
4.客户端和服务器互相告知,开始加密过程。

HTTP2.0和HTTP1.X相比的新特性

二进制:HTTP1.x的解析是基于文本。文本的表现形式有多样性,而二进制实现方便且健壮。

多路复用:即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。

header压缩:HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。

服务端推送:例如客户端收到sytle.css数据的同时,服务端会将sytle.js的文件推送给客户端,当客户端再次尝试获取sytle.js时就可以直接从缓存中获取到。

    原文作者:HTTP
    原文地址: https://segmentfault.com/a/1190000018366212
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞