简述
当浏览器发出一个http请求会经历这些过程,首先会去查找本地的DNS服务器查找有没有对应的域名ip地址,如果没有则会向上级层层查找,直到找到根DNS服务器,如果找到则返回当前域名的ip,没回返回未找到,我们都知道每台计算机都会对应一个ip地址。现在开始传输数据,首先把我们的数据在应用层加工组成数据包,然后到传输层这时候TCP会建立链接通道组装数据,接下来是网络层进行路由寻址对IP地址的数据包装,进去数据链路层然后进行发送数据。这是一个简单的HTTP请求过程。
HTTP数据的传输过程
首先会HTTP数据进行包装,在应用层(应用程序的首部 加上用户数据)——>把应用层数据传输层加上TCP首部 组装成TCP数据 ——>把数据传入到网络层,把IP首部加到TCP组装好的数据前组成IP数据段——>进入数据链路层加上以太网的首部组成以太网帧。
组装数据模型大概是这样
数据的传输是从一台电脑传输到另一台电脑之上,到了另一台计算机还要继续从数据链路层接收然后逐层传递到计算的应用层。
TCP三次握手四次挥手
使用TCP协议通信双方必须先建立链接,然后开始传输数据,为了确保连接双方可靠性,在双方建立链接时,TCP协议进行了三次握手。
- 第一次握手:客户端发送带SYN标点连接请报文段,然后进入SYN_SEND状态等待服务端确认。
- 第二次握手:服务端接收到客户端的SYN报文后,需要发送ACK信息对这SYN报文段进行确认。同时还要自己发送SYN请求信息。服务端会将上述的信息放到一个报文段(SYN+ACK报文段)中,一并发送给客户端,此时服务端会进入SYN_RECV状态。
- 第三次握手:客户端接收到服务端的SYN+ACK报文段后,向服务端发送ACK确认报文,此时报文发送完毕,客户端和服务端进入ESTABLISHED状态,完成三次握手,然后开始传输人数据。
- TCP报文首部:
- 同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
- 确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;
- 终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放
简单再来描述一下,第一次发送请求后,服务端接收到了消息,说明客户端的发送功能是没有问题的,第二次服务端向客户端发送确认,客户端收到说明服务端的信息,说明客户端是发送跟接收都没有问题,而客户端收了服务端的消息,说明服务端接收跟发送都没有问题,第三次发送的原因是,服务端不知道自己发送有没有成功,所以客户端要发送一下来确认。
HTTP知识点
HTTP结构分析
图引用自mdn
- 报文头
请求报文头分为四种类型,通用的报文头、请求报文头、响应报文头
-
报文头一般是由起始行, 方法、路径、http版本
- 起始行 一行起始,用于描述请求方法 路径或者版本,或者是对应的状态,成功或者是失败,总是单行的。
GET / HTTP/1.1
- 头部 可选的HTTP请求头集合,用于描述消息正文
- 空行 一个空行指示所以关于请求的元数据已经发送完毕
- 实体 请求报文对应请求体,响应报文对应响应体
-
请求头分类
- 通用报文头
Cache-Control: 控制缓存 Connection: 管理连接 Date:报文创建时间 Pragma: 报文指令 Upgrade: 升级协议 Via: 代理服务器相关信息 等...
- 请求报文头
Accept:可接受的媒体类型 Accept-Charset: 优先字符集 Accept-Language: 优先的语言(比如中文、英文的) Accept-Encoding: 优先的内容编码 Authorization:web认真信息 Host:请求资源所在服务器地址 If-Match: 比较实体标记 If-None-Match: 比较实体标记 If-Range: 资源未更新时发送实体Byte的范围请求 Referer: 对请求中的URI的原始获取方 User-Agent:HTTP客户端程序信息 等...
- 响应报文头
Accpet-Range: 是否接字节范围请求 Age:推算资源创建经过时间 ETag:资源匹配信息 Location: 令客户端重定向至指定URI Server:HTTP服务起的安装信息 Vary:代理服务器的缓存管理信息 WWW-Authenticate:服务器对客户端的认证信息
- 实体报文头
Allow: 资源科支持HTTP方法 Content-Encoding: 实体应用的编码方式 Content-Language: 实体的使用语言 Contet-MD5:实体报文摘要 Content-Range:实体主题的位置范围 Content-Type:实体主体的媒体类型 Expires: 实体主体过期日期时间 Last-Modified:资源最后修改日期 等等...
URI、URL与URN
URI可以被视为定位符、名称或者兼备。URI文法由URI协议名(例如http、ftp、mailto、file),一个冒号,和协议对应的内容所构成。[协议名]://[用户名]:[密码]@[主机名]:[端口]/[路径]?[查询参数]#[片段ID]
hierarchical part
┌───────────────────┴─────────────────────┐
authority path
┌───────────────┴───────────────┐┌───┴────┐
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
└┬┘ └───────┬───────┘ └────┬────┘ └┬┘ └─────────┬─────────┘ └──┬──┘
scheme user information host port query fragment
urn:example:mammal:monotreme:echidna
└┬┘ └──────────────┬───────────────┘
scheme path
- URI 编码 URI使用ACSII进行编码,如果URI中包含有非ASCII字符集中的字符,要对其进行编码,URL中一些保留字符,如果“&”表示参数分隔,如果要在URI中使用这些保留字,那就需要使用“%编码”规范,对URI中属性ASCII字符集的非保留字不做编码,对URI中的保留字需要取起需要其ASCII内码,然后加上“%”前缀将该字符进行编码,对于非ASCII字符需要取Unicode内码
HTTP请求方法
- GET get请求访问被URI识别的资源,指定资源经过服务端解析后返回相应内容. 特点
-
- url中直接带着参数,无法进行保密,自动会保存在浏览器的历史记录中
-
- 传输的数据量不大(不同浏览器运行传输的内容不一样)
- POST post 方法与GET功能类似,一般用来传输实体的主体,POST主要目的不是为了获取响应的内容,而是为了提交数据。 特点
-
- 传输在请求体中,保密新比get搞,浏览器中不会被主动记录
-
- 可以传输的数据量比较大
- PUT put方法一般用与更新数据库中的某个对象
- PUT与POST最大的不同是。put是幂等的,而POST不是幂等的。 幂等性参考
- HEAD 类似于get,用于获取报文头
- DELETE 请求服务器删除指定的资源,没有安全机制 与PUT方法一样
- OPTIONS 用来查询针对请求URI指定的资源支持的方法
- TRACERT 回显服务器收到的请求,主要用于测试或诊断
tracert www.baidu.com
- CONNECT 开启一个客户端与所请求资源与之间的双向沟通的通道,它可以用来创建隧道
CONNECT www.example.com:443 HTTP/1.1
HTTP 状态码
是用以表示网页服务器超文本传输协议响应状态的3位数字代码。
- 1xx 表示消息,这一类的状态码,代表请求已经被接受,需要继续处理。这类响应是临时响应,包含状态行和某些可选的响应头,并以空行结束。
101 Switching Protocals 在HTTP升级为WebSocket 的时候,如果服务器同意更变,就会发送状态码101
- 2xx 表示成功,这一类的状态码,代表已经成功被服务端接收,理解,并接受。
200 OK 请求已成功, 请求所希望的响应头或数据实体返回
202 Accepted 已接收,但为处理完成
206 Partial Content 服务器成功处理了部分GET请求
- 3xx 表示重定向,这类状态码代表需要客户端采取进一步的操作才能完成请求,通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location域中声明
301 Moved Permanently 永久移动,请求的资源已经被移动到新的URI,浏览器会自动定向到新URI,今后任何新的请求都使用新的URL代替
302 Moved Temporarily 临时移动,但是资源只是临时被移动,客户端应继续使用原有的URI
304 Not Modified 当前HTTP已经被缓存
- 4xx 表示请求错误,这类状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理,除非响应的是一个HEAD请求,否则服务器就应该返回一个解释当前错误状态的实体,以及这是临时的还是永久的状况。这些状态码适用于任何请求方法。浏览器应当向客户端显示任何包含在此类错误响应中的实体内容
400 Bad Request 客户端请求语法错误,服务端无法理解
401 unauthorization 要求客户端进行身份证认真
403 Forbidden 服务器器理解用户请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端发送的请求找到资源(网页)
- 5xx 表示服务器错误,这类的状态码代表了服务器在处理请求过程中有错误或者异常状态发生,也可能是服务器一时到以前的软硬件资源无法完成对应请求的处理,除非这是一个HEAD请求,否则服务器应当返回一个解释当前错误状态及这个状况是临时的还是永久的解释信息实体。浏览器会向用户展示任何在当前响应中被包含的实体。
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 客户端的请求还不支持
502 Bad Gateway 服务器正常,但是访问出错
HTTP的特点
-
请求-应答模式(客户端/服务端模式)
由客户端向服务器发发送请求,服务器响应请求,并进行响应服务,步骤01连接服务器02客户端发送请求03服务端发响应04关闭连接。
-
传输可靠 HTTP传中使用的TCP建立通道,TCP经历三次握手后才服务端与客户端互相确认后才进行数据传输,所以比较可靠。
-
灵活 HTTP允许传输任何类型的数据对象,可以用Content-Type来设置。
-
无状态 对于事务处理没有记忆,缺少状态意味着如果后续需要处理前面的信息,则它必须重传,这样可能导致每次连接传送的数据量大。在服务器不需要保存更多状态之前信息,所以无状态反而减少了网络开销,所以成了http的优点
HTTP缓存
为什么使用HTTP缓存?因为静态资源非常多,每次打开相同的页面,使用的流量都非常大,如果把有些静态资源缓存,这样下次访问的时候只请求更新文件,这样速度更快,更省流量。
- HTTP 缓存头部字段
- expires 时间是GMT时间,本地的电脑的时间可以修改,与服务器的时间不一致,这是一个缺点,后来http1.1中增加了max-age来解决这个问题,max-age加秒数。max-age的优先级会高于expires。协商缓存中Etag的优先级会高于last-modifed。
- Cache-control 请求头响应头,缓存控制字段
- no-store 请求响应头,缓存控制字段
- no-cache 缓存,但是浏览使用缓存前,会请求服务器判断资源是否更新
- max-age:请求缓存多少秒后再发起请求
- s-max-age:代理服务器请求资源缓存后的x秒不再发起请求,值对cdn缓存有效果
- public :客户端和代理服务器(CDN)都可以缓存
- private: 只有客户端缓存
- last-modifed GTM时间服务器发送给客户端
- ETag 服务端对资源进行的一个资源标识
- If-None-Match:请求头,缓存资源标识,游览器告诉服务器(上次请的资源的ETag),和当前的ETag对比
- HTTP 缓存工作方式
- 让服务器与浏览器约定一个文件过期时间Epires
- 让服务器与浏览器在约定过期的时间的基础上,再加一个文件最新修改时间的对比Last-Modified与If-Modified-Since
- 让服务器与浏览在过期时间Expires+Last-Modified基础上,增加文件内容唯一对比表示-ETag与If-None-Match,Expires不稳定,再加入一个max-age代替
内容协商机制
指定客户端和服务器端响应的资源内容进行交涉,然后提供给客户最为合适的资源。内容协商会以响应资源的语言,废物及,编码方式底层座位判断的基准。
- 协商方式
- 客户端驱动 客户端发请求,服务器发送可选项列表,客户端作出选择后在发送第二次请求。
- 服务端驱动 服务器检测客户端的请求头部集并决定提供哪个版本的页面。
服务器驱动内容协商-请求首部集
Accpet 告诉服务器发送何种媒体类型 Content-Type
Accept-Language: 告诉服务器发送何种语言 对应响应 Content-Language
Accept-Charset 告诉服务器用何种字符集 对应响应Content-Encoding
Accept-Encdoing 告知服务器采用何种编码方式 对应 响应 Content-Type
服务器驱动内容协商-近似匹配,例如: Accpet-Language:en,en-us;q=0.9,fr;q=0.5;zh,zh-CN;q = 0.2
q就是权重,优先匹配哪个内容
- 透明协商 某个中间设备(通常是缓存代理)代表客户端进行协商,而不是一个http标准的驱动所以用非常少见。
HTTP断点续传和多线程下载
- 断点续传是下载的时候暂停下载。
- 多线程下载文件分块下载。 HTTP是通过Header哩的参数实现的,客户端发送请求时对应的是Range,服务器响应时对应的是Content-Range.
- Range: 用于请求头中,指定第一个自己的位置和最后一个字节的位置,一般格式 一般格式Range:(unit=first by position)-(last byte position)
从第一个字节到499
Range:byte=0-499
从第500个字节到999
Range:bytes=500-999
从第500个字节到结束位置
Range:bytes=500-
从500到600开始并且从600到999
Range:bytes-500-600, 600-999
- Content-Range: 用于响应头中,在发出带Range的请求后,服务器会在Content-Range头部返回当前接受的范围和文件总大小。 一般格式Conent-Range:bytes(unit first byte position)-(last bytes position)/(entity length)。响应完成后,返回的响应头内容也不通
- HTTP/1.1 200 OK(不适用断点续传方式)
- HTTP/1.1 206 Partial Content(使用断点续传方式)
- 断点续传过程
- 客户端下载一个1024k的文件,已经下载了其中的512k。
- 网络中断,客户端请求续传,因此需要在HTTP头中申明本次需要续传的片段:Range:bytes=512000-这个通知服务器,从文件的512k位置开始传输文件 3.服务端收到断点续传请求,文件的512k位置开始传输,并且在HTTP头中增加:Content-Range:bytes 512000-/1024000 ,并且此时服务端的返回HTTP状态是206.
HTTP状态管理
HTTP有一个缺点是无状态,每次请求都是一个新的。所以这这时候就需要某种机制来记录这种状态。
- cookie 实际上是一小段文本信息,是服务器发送到用户浏览器并保存在本地的一小块数据,如果服务器需要记录该用户状态,服务器会告诉浏览器设置一下cookie,浏览器自动会设置cookie以key/value。下次请求同一网站会自动发送该cookie服务器。
Set-Cookie: <cookie名>=<cookie值>
服务器通过该头部告知客户端保存 Cookie 信息。
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
[页面内容]
对该服务器发起的每一次新请求,浏览器都会将之前保存的Cookie信息通过 Cookie 请求头部再发送
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
- cookie特点
- 大小和个数有限制 一般最大是4097个字节。个别浏览器没有个数限制,chrome限制在53个其他的浏览器比53个少。
- cookie 具有过期时间,可以通过设置expires、max-age来设置保存时间,不设置默认是临时存储,即关闭浏览器就会消失
document.cookie = "expires=时间/max-age=秒"
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
- 具有同源策略。 Domain 和 Path 标识定义了Cookie的作用域:即允许 Cookie 应该发送给哪些URL
- Domain 属性 指定了哪些主机可以接受cookie,如果不指定,默认为origin,不包含子域名。如果指定了Domain,则一般包含资源,因此,指定Domain比省略它限制少的多。
Domain设置
例如:如果设置 了Domain=mozilla.orgm则cookie也包含在子域名中(如developer.mozilla.org)
- Path path标识指定了主机下的哪些路径可以接受Cookie(该URL路径必须存在于请求URL中)。以字符%x2F("/")作为路径分隔符,子路径也会被匹配。
例如: Path = /docs ,则以下地址都会匹配
/docs
/docs/web.
/docs/web/HTTP
- SameSite attribute SameSite Cookie 允许服务器要求某个cookie 在跨站请求时不会被发送(其中Site由可注册域名定义),从而可以阻止跨站伪造请求(CSRF),SameSite cookies是相对较新的一个字段。所有主流浏览器都已经得到支持
例子
Set-Cookie: key=value; SameSite = Strict
属性值
none 浏览器会在同站请求,跨站请求下继续发送cookies,不区分大小写
Strict 浏览器将只在访问相同站点时发送cookie。(在原有Cookies的限制条件上加强,如上文“Cookie” 作用域)
Lax 与strict 累死,单用户从外部站点导航至URL时(例如通过链接)除外。在新版本浏览器中,为默认选项,Same-site cookies将会为一些跨站子请求保留,如图片加载或者iframes的调用,但只有当用户从外部站点导航到URL时才会发送。如link链接。
- Cookie prefixes cookies 名字前缀有__Secure- 或者__Host- 只有在使用来自安全(https)来源的secure属性进行设置的情况下使用。 此外带有__Host-前缀的cookies的路径必须为/(表示主机上的路径),并且不得就要Domain属性。
安全来源(HTTPS)都被接受
Set-Cookie:__Secure-ID=123;Secure;Domain=example.com
Set-Cookie:__Host-ID=123;Secure;Path=/
//由于失去secure 属性被拒绝
Set-Cookie: __secure-id=1
// 由于没有Path被拒绝
Set-Cookie:__Host-id=1;Secure;
// 由于没有设置Domain被拒绝
Set-Cookie:__Host-id=1;Secure;Path=/;Domain=example.com
由于JavaScript可以通过Document.dookie访问cookie 可以操作cookie,可以设置HttpOnly标记为Cookie就不能被修改了。
- session seesion是另一种记录客户端状态的机智,保存在服务器上。客户端浏览器访问的时候,服务器把客户端信息以某种形式记录在服务器上
HTTTP2.0
HTTP2.0在基于HTTP1.0语义语义,HTTP方法,HTTP的状态码,HTTP的URI和HTTP首部字段,做了突破HTTP1.1的标准性能限制,实现了低延迟、高吞吐量。关键是在二进制分帧计技术上面。
- HTTP2.0的首部压缩 HTTP2.0的首部压缩,是指使用首部表,来跟踪存储之前发送的键值对,对于相同的数据不再通过每次请求和响应发送,通信期间键值对几乎不会改变,比如加上用户代理,比如可接受的媒体类型。
- 二进制分帧技术 HTTP2.0客户端和服务器可以吧HTTP的消息分解成互不依赖的数据帧,然后乱序发送,然后在另一端重新组装,同一个连接上可以从多个不同的方向的数据流在传输,所以客户端可以乱序发送数据流,也可以接收数据流。
- 优势
- 多个请求一起发送,请求之间互不影响
- 并行交错互相之间互不影响,
- 使用一个连接即可发送多个请求和响应
- 消除了不必要的延迟
HTTPS
HTTP和HTTPS本质上是两种不同的协议,HTTP在应用层,HTTP是超文本传输协议,在网络上传输方式以明文的方式,很容易被拦截,HTTPS是HTTP+TLS 或者是HTTP+SSL,TLS是传输层加密协议,也是SSL协议的前身。
- HTTP功能介绍
- 内容加密,防止被第三方拦截。
- 身份认证,数字证书、根据证书来进行身份认证,这些证书都是被各大公司认可的,一般会内置在浏览器中。
- 数据完整性——防止被第三方修改
- HTTPS 的使用成本
- 证书费用及更新维护
- HTTPS降低了用户访问速度,因为加了一层TLS层
- 消耗CPU资源
- HTTPS对性能的影响
- 协议交互增加了网络RTT(round trip time 往返时延)
- 加密解密所带来的耗时, 浏览器计算耗时,服务端计算耗时
- CA证书 证书组成 ,证书机构颁发,机构存私钥加密(服务端拿公钥)机构私钥加密(证书签名)
- 证书流程 服务端生成公钥key1, 发送给证书结构,证书机构把证书发送给服务器,然后客户端与服务器通信的时候,服务端会把证书发送给客户端,客户端验证证书的真伪,然后继续用证书的公钥解密出服务端的公钥key1,将准备进行对称加密的key2用公钥key1加密,加密结果val3。 验证证书,就可以从证书机构中获取CA证书的公钥解密出证书的签名,客户端会按照同样的规则(用相同的Hash算法对原始信息生成消息摘要)也生成一个签名,如果两个签名一样说明证书是有效的。
跨域
跨域是概念是指客户端与服务器交互的时候,协议不同端口不同域名不同,这就叫做跨域。
- 跨域的限制
- 不能修改对方的网站的DOM
- 不能访问对方的cookie、IndexDB和LocalStorage
- 解决跨域的方法
- CORS 是W3C的一个标准,全称是跨域资源共享,它需要浏览器和客户端的共同支持,具体来说,就是要在服务器的响应中加上特定的响应头。
简单请求
请求的方法GET/POST/或者HEAD
请求头的取值范围:Accept /Accept-Language/Content-language/Content-type(仅限三个值application/x-www-form-urlencode/multipart/form-data、text/plain)
在请求的时候回在请求头中自动加以个Orgin字段,用来说明是来自哪个源,服务器拿到之后会添加对应的Access-Control-Allow-Orign字段,如果Origin 不在这个字段的范围中,那么浏览器就会响应拦截。 一设置为Access-Control-Allow-Origin * 允许不同源的清
- Access-Control-Allow-Credentials 这个字段表示是否允许送送cookie,对于跨域请求是指置为false的。如果浏览器需要拿到这个cookie,需要在这个响应头中加true,前端设置也需要设置withCredentails属性. Access-Control-Allow-Methods: GET、POST、PUT Access-Control-Allow-Headers: x-cutom-Header Access-Control-Allow-Max-age: 预检请求的有效期。
非简单请求
- JSONP script的标签不一样它可以通过src天上目标地址二发出GET请求,实现跨域请求并拿到响应。
- nginx反向代理
- 正向代理 正向代理是指,一个位于客户端和目标服务器直接的服务器,为了从目标获取资源,客户端向代理服务器发送一个请求并指定目标服务器,然后代理服务器转交到目标服务器并获得内容返回给客户端。
- 反向代理 反向代理是指,以代服务器来接收客户端请求,然后将请求发送给内部的服务器,并将服务器得到的返回结果返回给客户端。此时代理服务器对外表现为一个反向代理服务器。
- 两者的优缺点
- 安全上来讲
- 正向代理运行客户端访问它任意网站,并且可以知道真正的服务器
- 反向代理客户端不能直接知道自己访问的是哪个代理。
- 使用方法
- 正向代理是浏览器进行配置,与服务器无关,可以对服务端进行隐藏
- 反向代理是服务器端配置,对浏览器是透明的
- 用途上
- 反向代理可以为后端的多台服务器提供负载均衡,或者为后端提供反冲服务器
- 正向代理可以在防火墙的局域网客户端提供访问internet的途径,正向代理可以使用缓存特性减少网络使用率 参考segmentfault 参考MDN