http知识点
对于http的报文格式就不多细说了,因为做为前端开发,我们需要知道前后端联调时的请求和响应之间请求头和返回头之间的关系和每个字段中的涵意,静态文件资源在加载时我们所观察到能够性能优化的点,和一些日常请求报错如何去解决的坑,更重要的是面试的时候如何去从容的应对面试官。
谈到http,就少不了最常见的一个问题,跨域,当我们使用api接口进行数据请求时,浏览器的控制台控制台中,报出了这样的错误,恭喜你,你跨域了。
在本地向不同域请求的时候,浏览器会做一个Origin请求头的验证,如果没有设置,在不同域名下或者本地请求时浏览器会向服务端发送请求,服务端也会客户端发送对应的值,但是浏览器考虑到安全策略,会进行一个关于头信息的报错,此时对于后端来说,需要在response的返回头中加入
来告诉浏览器我允许你进行一个跨域请求,不用报错,把值返回给请求者,这样你就可以安然的拿到数据。同时这样也会导致任何一个域名发送过来的请求,都允许跨域的情况下,可以针对’Access-Control-Allow-Origin’: ‘此处设置指定的域名’
|
|
如果不超过以上的限制,后端则只需要提供一个允许跨域的Origin就可以了,如果在请求方法超过了以上三种,需要添加’Access-Control-Allow-Methods’: ‘PUT’,同样浏览器为了安全,不允其它请求方法在台端没有设置允许的方法中进行一个跨域请求
在非同源的请求情况下,浏览器会首先进行Option请求,所谓的预请求,就是试探性请求,向服务端请求的时候,发现此接口设置了允许对应的请求方法或者请求头,会再次发送真正的请求,分别一共会向后台发送两次请求,拿自己想要的数据,在OPTION请求时,服务端也会返回数据,但是在浏览器层被做了屏闭,如果没有检测出对应的跨域设置则会报出对应的错误。
###可以减少预请求次数
在本地联调时,每次发送一个非简单请求时都会发送一个预请求,预请求也是一个花费时间和资源的操作,就像一次实名质认证过了,在一定时间内就不用实名质认正了,原理一样,如果当前请求的域名第一次认证通过,则在一定的时间内不需要进行一个二次认证,但是需要进行一次认证的时间控制,通过’Access-Control-Max-Age’: ‘860000’,返回,一旦在这个时间之内再次发送时,直接发送真正的请求,不通要再通过预请求Option方法进行一个探测认证。
cache-control 的使用场景和性能优化
cache-control这个东西就是对服务端拉取的静态资源打上一个缓存标志
对于cache-control可以设置几种模式,通常前端工程师又需要知道那几种模式
max-age = 10000 (以秒为音位,根据需求设定)
no-cache (每次进行请求时都要向服务端进行验证,需要配合etag,Last-Modified)使用
no-store (每次请求都需要向服务端拉取新的资源)
privite (私有的,不经过代理缓存)
public (公有的,如果本地失效,代理缓存存在的话可以从代理缓存进行通知用过期的资源)
max-age
当加载完资源时,浏览器会自动给我们存储到内存当中,但是浏览内部的失效时间是由内部机制控制的,在用nginx做静态资源的时候,在刷新的时候,浏览会向服务端再次发送是否过期的认证,在资源缓存时间的确定情况下,通过max-age指定强缓存后,浏览器再次加载同样的资源文件时,只需要从memory或者disk上面进行拉取复用
达到以上的功能需要在返回资源的服务端的对返回的资源设置’cache-control’: ‘max-age=时间(以秒为单位)’,当再次刷新页面的时候,在设置的时间之内,刷新页面,不清除缓存的情况下都会重新拉取内存了中的缓存资源。
no-cache
no-cache 字面的字意是不缓存的意思,但是很容易迷惑人,但是本质的函意,意味着每次发送请求静态资源时都需要向服务端进行一次过期认证,通常情况下,过期认真证需要配合(etag和Last-Modified)进行一个比较,这个话题后继再展开讨论,如果验证并没有过期,则会发送304的状态码,通知浏览进复用浏览器的缓存
no-store
no-store 代表每次资源请求都拉取资源服务器的最新资源,就算同时设置max-age , no-store, no-store的优先级则最高,此时max-age则不生效,同样的会从服务端拉取最新的资源
private vs public
在资源请求时,有些情况不会直接到原资源服务器发送请求,中间会经过一些代理服务器,比如说cdn,nginx等一些代理服务器,如果写入public的情况下,所有的代理服务器同样也会进行缓存,比如说s-maxage就是在代理缓存中生效的,如果本地max-age过期了,则会通过代理缓存,代理缓存并没有过期,会告诉浏览器还是可以用本地过期的缓存,但对于private中间代理服务器则不会生效,直接从浏览器端向原服务器进行一个验证。
###缓存验证 Last-Modified 和 Etag
Last-Modified
最后修改时间,一般在服务端,对文件的修改都会有一个修改时间的记录,在nginx做静态资源时,nginx会返回一个Last-Modified最后修改的时间,在浏览器再次请求的时候,会把对应的If-Modified-Since和 If-UnModified-Since在请求头中再次发送给服务端,告诉服务端上次你给我文件改动的时间,但是Last-Modified只能以秒为单位,在有些情况下,是不够精确的
Etag
是一个更加比较严格的验证,主要通过一些数据签名,每个数据都有自己的唯一签名,一旦数据修改,则会生成另一个唯一的签名,最典型的做法就是对内容做一个hash计算,当浏览器端向服务端再请求的时会带上 IF-Match 或者 If-Non-Match,当服务端接收到后之后会对比服务端的签名和浏览器传过来的签名,这也是弥补了Last-Modified只能以秒为单位,在有些情况下,是不够精确的情况
Last-Modified和Etag 配合 no-cache 使用
通常只会在 cache-control 在 no-cache的情况下,浏览器也会对资源进行一个缓存, 同时会对服务端进行一个认证过期,一旦服务端返回304状态码,则说明可以复用浏览器的缓存,则会向服务端重新请求数据。
cookie的策略机制
cookie则是一个服务端和用端之间一个像身份证认证一样的东西,一旦后端在返回头中设置了cookie,则在response中会出现设置的cookie数据,同时也会存在浏览器的application/cookie中,当每次发送请求的时候都会在request的头中带上当前域名下的cookie信息