http协议
五层模型介绍
- 物理层:主要作用是定义物理设备如何传输数据,网线,光纤
- 数据链路层:在通信实体间建立数据链路链接
- 网络层:为数据在节点之间传输创建逻辑链路
- 传输层:主要有两个协议 TCPIP 和 UDP ,它向用户提供了可靠的端到端的服务。
- 建立起了自己电脑到百度服务器的链接,它们两端如何去传输数据,它的传输数据的方式 ,都是在这层定义,传输层向高层屏蔽了下层数据通信的细节
- 应用层: 为应用软件提供了服务 http / ftp 是构建于TCP 协议之上,屏蔽了网络传输相关细节
解析:
- 经典五层模型:
- 1.物理层:一些硬件之类
- 2.数据链路层:0101之类的
- 3.网络层:
- 4.传输层:为用户提供end-to-end服务,向高层屏蔽了下层数据通信的细节
- 5.应用层(http):构建于TCP之上
HTTP协议的发展历史
第一个版本 HTTP / 0.9
- 只有一个命令 GET
- 没有HEADER 等描述数据的信息
- 服务器发送完毕就关闭
第二个版本 HTTP / 1.0
- 增加了很多命令
- 增加了status code 和 header
- 多字符集支持、多部分发送、权限、缓存 等等
- 1,增加命令比如POST、PUT、Header
- 2,增加status code和header内容,
- (1)status code用来描述服务端处理某一个请求之后,它的一个状态,
- (2)header,对应的是,不管是发送还是请求的相关的一些数据,它的描述以及我们对这部分数据如何进行操作的一个方法。
第三个版本 HTTP / 1.1
- 持久链接
- pipleine
- 增加了 host 和其他一些命令 (在同一个物理服务器可以同时跑很多服务)
第四个版本 HTTP / 2.0
- 所以数据都是以二进制传输
- 同一个链接里面发送多个请求不在需要按照顺序来
- 头信息压缩以及推送等提高效率的功能
- 1,弄清楚一个概念,HTTP请求与TCP请求不是一个概念,在同一个TCP请求可以发送多个HTTP请求,以前的协议版本不能这么做,但是现在HTTP1.1.1里面可以这么做,而且在HTTP2里面是会更大的去优化相关的一些东西,来提高HTTP传输效率以及服务器的性能。
- 2,这边TCP连接对应多个HTTP请求,而一个HTTP请求肯定在某一个TCP连接里面去定义发送的。
HTTP三次握手
为了防止服务端开始无用的链接,网络传输是有延时的,传输过程中防止丢包,造成重复创建链接,资源浪费,所以设置三次握手。为了规避网络传输延时。
1.客户端发起一个我要连接的数据包请求给服务器,里面会有一个SYN的标志位,标志这是一个创建请求的数据包
2.服务端接收到数据包后知道有一个客户要和它建立链接了,然后会开启一个TCP socket 端口,开启之后返回数据给客户端,数据包含 SYN标志位,ACK= X+1,Seq=Y
3.客户端拿到数据包后意味着服务器端允许创建TCP连接,然后发送数据包 ACK = Y+1,Seq=Z
http只有请求和响应这个概念,没有链接这个概念
在http1.0的时候,在http request的时候,在里面发起三次握手,创建TCP链接,然后再发起请求,请求结束后则关闭TCP链接
在http1.1的时候,可以通过申明这个链接,可以保持在那里,后面就不需要三次握手开销
在http2.0可以请求并发,只需要一个TCP链接
第一次握手,用户向服务端发送请求,SYN=标志位=创建请求的数据包,Seq=X为数字,一般为1。
第二次握手,服务端返回请求
第三次握手,客户端再次传回服务端
URI,URL和URN
- URI:统一资源标志符,用来标识互联网上的信息资源,包括URL和URN
- URL:统一资源定位器
- URN:永久统一资源定位符,在资源移动后还能被找到
urn作用在于搬动了资源后仍然可以直接找到,相当于面向对象命名。
框架一般都会出现这个概念,方便多次调用的东西都可以理解为urn,-。
个人理解
完整的URL地址:http://user:pass@host.com:80/path?query=string#hash
- http:// 协议
- user:pass@ 代表访问资源的身份使用用户名和密码
- host.com 用来定位资源的服务器在互联网中的位置(可以是IP 也可以是 域名)
- :80 端口,每台物理服务器可以跑很多软件的web服务,端口就是监听物理服务器上面某个具体的web服务
- /path 路由,web 服务器里面的内容可以通过路由进行定位
- ?query=string 搜索参数
-
hash 查找文档的某个片段
HTTP报文格式
HTTP方法
用来定义对于资源的操作
常用有GET、POST
从定义上讲有各自的语义
HTTP CODE
定义服务器对请求的处理结果
各个区间的CODE有各自的语义
好的HTTP服务可以通过CODE判断结果
method :
GET:获取数据
POST:创建数据
PUT:更新数据
DELETE : 删除数据
- http方法:用来定义对于资源的操作
- http code :定义服务器对请求的处理结果
- 100-199代表操作要持续进行
- 200-299代表成功
- 300-399需要重定向
- 400-499代表请求有问题
- 500-599服务器错误
CORS跨域请求的限制和解决
- jsonp实现的原理:浏览器允许在某些标签里面写路径加载,是允许跨域的。
- JSONP是服务器与客户端跨源通信的常用方法,它的基本思想是,网页通过添加一个<script>元素,向服务器请求数据,这种做法不受同源政策限制(亦或者img/src等其他类似访问link的标签)。
- 跨域概念:一般的,只要网站的 协议名protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用。而这是不允许的,想象一下假如允许的话,那么你登陆银行网站,又不小心登陆了一个黑客网站,黑客网站就可以读取银行的cookie进而冒充客户为所欲为。
- 跨域原理:请求发送成功,服务器也接受到了,内容也已经返回了,但浏览器在解析了返回的内容之后,发现这是不允许的,所以拦截掉了内容。
- 浏览器如果接收到的服务器返回的响应头中包含 Access-Control-Allow-Origin 则视为允许跨域,该属性设置为 * 则允许所有网站跨域,但是并不安全,所以我们往往设置为我们允许的网站(类似白名单的作用),如截图中仅允许 http://127.0.0.1:8888 的请求跨域访问。但该值仅允许设置为一个,如果需要设置多个,常用做法是在代码中进行判断,动态设置该值即可。
- 跨域原理:请求发送成功,服务器也接受到了,内容也已经返回了,浏览器在解析了返回的内容之后,发现这是不允许的,所以拦截掉了内容,并在命令行报错,其实是浏览器提供的功能,如果在curl里面是没有跨域概念的。
- 1,通过 Access-Control-Allow-Origin 响应头 来实现跨域请求
- 2,通过JSONP来实现跨域请求
CORS跨域请求的限制及预请求限制
在跨域的时候
1.默认允许的方法只有GET、HEAD、POST ,其余 PUT 、DELETE 都是默认不允许的,浏览器会预请求去验证的。
2.默认允许的 Content-Type 有 text/plain、multipart/form-data、application/x-www-form-urlencoded 其余Content-Type 都需要 预请求验证
3.其他限制:请求头限制、XMLHttpRequestUpload 对象均没有注册任何事件监听器、请求中没有使用 ReadableStream 对象
Cache-Control的含义和使用
客户端从服务器请求数据经历如下基本步骤:
1、如果请求命中本地缓存则从本地缓存中获取一个对应资源的"copy";
2、检查这个"copy"是否fresh,是则直接返回,否则继续向服务器转发请求。
3、服务器接收到请求,然后判断资源是否变更,是则返回新内容,否则返回304,未变更。
4、客户端更新本地缓存。
no-cache的作用是:强制客户端跳过步骤2,直接向服务器发送请求。也就是说每次请求都必须向服务器发送。
must-revalidate:作用与no-cache相同,但更严格,强制意味更明显。但这只是理论上的描述,根据我在ff6上的测试,它几乎不起作用:只要请求的频率加快到一定程度,服务器就接收不到请求。
no-store:缓存将不存储response,包括header和body。测试结果表明,除每次请求都必发送到服务器外,响应代码均是200,且request并没有发送"If-Modified-Since"和"If-None-Match"头,这意味着缓存的确没有存储response。
以上三者都是要求客户端每次请求都必须到服务器进行revalidate,此功能还可以通过max-age实现: Cache-Control:max-age=100
有max-age,服务端内容更新后,希望客户端能获取新的静态资源
解决:加上hash码,内容不变,hash码不变,内容变了,hash码变了,请求的url变化,就可以获取更新的文件
重新验证:
must-revalidate:缓存过期后,必须去原服务端发送这个请求,重新获取这部分数据,验证是否真的过期
procy-revalidate:和上面的差不多,用在缓存服务器
其他:
no-store: 不能缓存,只能每次从服务器拿
no-transform:不压缩、转换返回内容
这些声明都没有强制效应
可缓存性:
public:http返回的内容经过的任何路径都可以对返回内容进行缓存
private:发起请求的浏览器才可以缓存
no-cache:可以在发起端进行缓存,要服务器验证才可以使用缓存
到期:
max-age=seconds 到期多少秒,再次请求
s-maxage=seconds 代替max-age 在代理服务器内生效
max-stale=seconds 返回的资源有这个属性,即便缓存已经过期,在这个时间内还可以继续使用已经过期的缓存
静态资源解决方案:把实际打包完成的js文件上的文件名上加上一串hash码,如果内容没有变化,hash码不会变化,如果内容有变化,则hash码也会变化。这样可以达到更新缓存的目的
no-cache:本地可以用使用缓存,但需要服务器验证后才能使用
no-store:本地和代理服务器都不能存储缓存,都需要从服务器端重新请求
no-transform:告诉代理服务器不能随便改变返回的内容
must-revalidate:当缓存到期后,不能直接使用本地缓存数据而需要重新验证
proxy-revalidate:缓存服务器上,必须去原服务器重新请求一遍,不能使用本地缓存
到期:
max-age=<seconds> 服务器缓存到期时间
s-maxage=<seconds> 代理服务器缓存的到期时间
max-stale=<seconds> 到期后,即便缓存过期,只要在max-stale时间内,依然有缓存
其他
1,no-store 本地和代理服务器都不可以存缓存
2,no-transform 代理服务器不要去改动返回内容
no-store(本地和代理服务器都不可以缓存),no-transform(主要用在代理服务器,不允许改动服务器返回的内容)
可缓存性,因为数据传输过程中可能存在多个代理服务器,则数据缓存中的public表示路径上所有(包括代理服务器)都可以对数据进行缓存;而private则代表只有发起请求的浏览器才能进行缓存;no-cache表任何不能缓存
Cache-Control是客户端的缓存。虽然服务端的文件变了但是url没有变,所以客户端依旧使用缓存的文件。前端常见的解决策略是,生成文件的hash码。
缓存头Cache-Control:
一、可缓存性(哪些地方可以缓存):public(任何地方都可以), private(发起请求的浏览器可以进行缓存), no-cache(任何地方都不可以)
二:时间限制:max-age = <seconds>, s-max-age = <seconds>(专用在代理服务器中),max-stale = <seconds>(发起请求端设置的)
三:重新验证:must-revalidate(时间过期必须去原服务端重新获取数据),proxy-revalidate(和must-revalidate类似,用于缓存服务器中)
缓存验证Last-Modified和Etag的使用
- 设置了etag、last-modified后,浏览器在第二次发起请求后就会把if-none-match和if-modified-since带上
HTTP验证头:
1,Last-Modified 上次修改时间
配合If-Modified-Since使用
对比上次修改时间以验证资源是否需要更新
2,Etag
数据签名,对响应内容产生一个唯一的字符串。
配合If-Non-Match使用
对比资源的签名判断是否使用缓存
304 :
如果客户端发送了一个带条件的GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个304状态码。简单的表达就是:客户端已经执行了GET,但文件未变化。
[站外图片上传中...(image-69e60e-1537155939039)]etag,数据签名.数据修改,资源的数据签名就会修改.例如hash两个属性:if-match,if-non-match里面放的etag值,对比服务端和客户端判断是否使用缓存
Cache-control:nocache 可以在发起端缓存但要在服务端进行验证是否可以缓存;last-modified:上次修改时间;if-modified-since,in-unmodified-since:服务器读取这两个值,看资源是否重新修改,服务器告诉客户端是否可以用缓存的资源
Cache-Control: nocache,每次浏览器发起对一个已经设置了Cache-Control资源的请求时,都会要到服务器端进行资源的验证。验证之后确定资源可以使用缓存,确定该资源可以使用缓存,才会读取本地缓存
cookie
domain
访问域设定
cookie只能一个域访问
a.com的cookie b.com不能访问
domain让a.test.com能访问test.com的cookie
不能跨域设置cookie,只能一级通过domain设置二级等
max-age:有效期多长
expires:到期的具体时间
服务端返回数据时通过set-Cookie设置到浏览器内,浏览器保存cookie后,在同域的访问内下次请求会自动带上
max-age 和 expires 设置过期时间
Secure 只在https的时候发送
httpOnly无法通过js访问,浏览器中还是有的。
cookie时效
如果没有设置时间,浏览器关闭失效。
'Set-cookie': ['id=123; max-age=30', 'name=lin'] : id=123->30s后失效
设置test.com以及test.com的所有二级域名享受到cookie
HTTP长连接
Connection:keep-alive(长)、close(短)
http2:信道复用 tcp并发发送http请求
http请求是在tcp上发送的,一个tcp可以发送多个http,http1.1是阻塞的
现在保持长链接比较多
应为多次建立tcp链接可能比长链接的开销更大
长链接可以设置timeout
同个tcp内是有先后顺序的
浏览器可以并发6个tcp
session
用cookie保存sesion将用户登陆key保存到cookie,每次用户请求时读取cookie值,定位用户信息
session:定位到用户
数据协商
服务端返回
X-Content-Type-Options : nosniff
服务端不接受contnettype的数据类型或没设置type,不主动预测类型
浏览器端会自动加上,也可以在ajax时设置
Accept:浏览器能展示的数据格式
Accept-Encoding:能接受的数据压缩格式
Accept-Language:希望接受的语言
User-Agent:系统名 内核 浏览器版本
数据协商:
根据客户端发来的要求,服务端返回对应的数据
Accept 属性
Accept(什么数据类型) Accept-Encoding(编码方式,压缩) Accept-Language(使用的语言) User-Agent(处于哪种系统环境)
Content属性
Content-Type Content-Encoding Content-Language
redirect
通过url去访问资源,资源不在原来的位置,服务器要告诉浏览器,请求的资源在哪里,浏览器再重新请求
Lacation:新url
302:临时跳转 每一次都要通过服务器跳转
301:永久跳转 第二次访问后,就不需要再通过服务器去跳转,是通过浏览器跳转的,被缓存了新url