A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 懒,羊羊 于 2018-7-13 10:12 编辑

     对于http的报文格式就不多细说了,因为做为前端开发,我们需要知道前后端联调时的请求和响应、请求头和返回头之间的关系和每个字段中的含义,静态文件资源在加载时我们可观察到的性能优化点,和一些日常请求报错如何去解决,更重要的是面试的时候如何去从容的应对面试官
简单跨域的解决方式
     跨域是一个老生常谈的话题,面试官问我如何解决跨域,以前只会和面试官说用webpack的 proxy做代理,叫后端大哥给我本地启一个nginx就可以了。在一些特殊的情况下,了解跨域根本性的知识点才能解决根本性的问题。
猿族前端 VS 猿族后端 java
后端说: 前端同志,我们先调一个get请求的一个接口,地址我给你,http://www.pilishou.com/getname/list
[JavaScript] 纯文本查看 复制代码
fetch('http://www.pilishou.com/getname/list', {[/size][/font][/color][/align]
    method: 'GET'

})

     前端操作中。。。
     写了一个这样的请求,听从后端大哥向服务端发送,此时浏览器报了一个这样的错误

[JavaScript] 纯文本查看 复制代码
Failed to load [url]http://http:[url=http://www.pilishou.com:]www.pilishou.com:[/url][/url] No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

     小白前端会说: 大哥,你这是什么接口,请求了还报错,你那里什么鬼!

     大牛前端会说: 大哥,帮个忙,你那里忘记设跨域头了。

     小白后端会说:大哥,你会不会调接口,报错还找我,我这里postman上面调的一点问题都没有

     大牛后端会说: 大哥,等一下,我的跨域头忘记设了,稍等

原理讲解:
     在本地向不同域请求的时候,浏览器会做一个Origin请求头的验证,如果没有设置,在不同域名下或者本地请求时浏览器会向服务端发送请求,服务端也会向客户端发送对应的值,但是浏览器考虑到安全策略,会进行一个关于头信息的报错,此时对于后端来说,需要在response的返回头中加入 'Access-Control-Allow-Origin': '*', 来告诉浏览器我允许你进行一个跨域请求,不用报错,把值返回给请求者,这样你就可以安然地拿到数据。同时这样也会导致任何一个域名发送过来的请求,都允许跨域。但是可以通过'Access-Control-Allow-Origin': '此处设置指定的域名'设定允许的跨域域名。

复杂跨域的解决方式
     此时前端唱起来一首抖音网红歌,我知道我对你不仅仅是喜欢!。。。。。
     后端说:小伙,这里有一个接口,需要遵循resutful接口,用PUT方法,http:www.pilishou.com/getname/update
     前端操作中。。。。

     
[JavaScript] 纯文本查看 复制代码
fetch('http://www.pilishou.com/getname/list', {[/size][/font][/color][/align]
    method: 'PUT'

})


     继续按部就班的写了一个这样的请求,然后又发现浏览器报了这样一个错误

     
[JavaScript] 纯文本查看 复制代码
Failed to load [url]http://http:[url=http://www.pilishou.com:]www.pilishou.com:[/url][/url] Method PUT is not allowed by Access-Control-Allow-Methods in preflight response

     小白前端会说: 大哥,你接口又怎么了,GET,POST都行,PUT怎么不行,肯定是你的问题,我别的什么都没动啊。
     大牛前端会说: 大哥,帮个忙,你把请求头中加一些允许跨域的方法。
     小白后端会说:大哥,你不会调接口,报错还找我,我这次postman上面调的还是一点问题都没有.
     大牛后端会说: 大哥,等一下,我加一些允许跨域的方法,稍等

原理讲解:
     在简单的跨域请求中 1. 请求方法是以下三种方法之一:HEAD、 GET、POST
     2.HTTP的头信息不超出以下几种字段: Accept、 Accept-Language、Content-Language、 Last-Event-ID、Content-Type
[JavaScript] 纯文本查看 复制代码
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
     如果不超过以上的限制,后端则只需要提供一个允许跨域的Origin就可以了,如果在请求方法超过了以上三种,需要添加 'Access-Control-Allow-Methods': 'PUT', 同样浏览器为了安全,不允其它请求方法在前端进行跨域请求
     同理复杂请求还包含着别的需要后端设置允许的一些跨域请求的方式,比如通常会出现的:
[JavaScript] 纯文本查看 复制代码
fetch('http://127.0.0.1:8887', {

    method: 'PUT',

    headers: {

        'x-header-f': '1234',

    }

})
报错信息:
[JavaScript] 纯文本查看 复制代码
Failed to load [url=http://www.pilishou.com:]http://www.pilishou.com:[/url] Request header field x-header-f is not allowed by Access-Control-Allow-Headers in preflight response.
解决方案:
[JavaScript] 纯文本查看 复制代码
需要服务端加上允许那些自定义头进行一个跨域仿问 'Access-Control-Allow-Headers': 'x-header-f'
[JavaScript] 纯文本查看 复制代码
fetch('http://127.0.0.1:8887', {

    method: 'PUT',

    headers: {

        'x-header-f': '1234',

        'content-type': 'json'

    }

})
报错信息
[JavaScript] 纯文本查看 复制代码
Failed to load [url=http://www.pilishou.com:]http://www.pilishou.com:[/url] Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
解决方案
[JavaScript] 纯文本查看 复制代码
需要服务端加上允许那些自定义头进行一个跨域仿问 'Access-Control-Allow-Headers': 'content-type'这个请求头信息
     cache-control 的使用场景和性能优化
     cache-control这个东西就是对服务端拉取的静态资源打上一个缓存标志
     对于cache-control可以设置几种模式,通常前端工程师需要知道几种模式
  • max-age = 10000 (以秒为单位,根据需求设定)
  • no-cache (每次进行请求时都要向服务端进行验证,需要配合etag,Last-Modified使用)
  • no-store (每次请求都需要向服务端拉取新的资源)
  • private (私有的,不经过代理缓存)
  • 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 和 EtagLast-Modified
     最后修改时间,一般在服务端,对文件的修改都会有一个修改时间的记录,在nginx做静态资源时,nginx会返回一个Last-Modified表示最后修改的时间.在浏览器再次请求的时候,会把对应的 If-Modified-Since和If-UnModified-Since在请求头中再次发送给服务端,告诉服务端上次你给我文件改动的时间,但是Last-Modified只能以秒为单位,在有些情况下,是不够精确的

Etag
     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信息

健值对方式设置
     在返回头中设置 'Set-Cookie': 'cookie内容'

设置过期时间
     通常情况,在不设置过期时间的时候,浏览器关闭的时候,则cookie,则会失效,我们可以通过max-age或者expire进行一个cookie失效时间的设置

不可获取的 cookie
     如果在不设置httponly的情况下,可以通过 document.cookie进行读取,在不同情况下,考虑安全性,可以通过httponly设置,使得 document.cookie无法获取。
https 下的 secure cookie
     如果设置了secure只有在https的服务下才会把字段写入application/cookie中,虽然在response有发送cookie这个字段,但是浏览器识别到不是https服务时,会进行忽略。

redirect 重定向的坑
     重定向在response中会有一个location字段进行重定义,比如说返回值/list,需要我们重定向到/list的页面,但是在响应码中,可以返回 302或者301

301 适合永久重定向
     301比较常用的场景是使用域名跳转。比如,我们访问 http://www.baidu.com 会跳转到 https://www.baidu.com 发送请求之后,就会返回301状态码,然后返回一个location,提示新的地址,浏览器就会拿着这个新的地址去访问。

302 用来做临时跳转
     302和301的区别则是设置了302如果再次访问则是从服务端再次拉取资源,然后进行重定向。301则是如果有缓存文件,则直接读缓存文件上响应头上的重定向位置,如果原服务端重定向的位置有变化,则只能通过用户清除缓存进行重新拉取新资源进行再次重定向,所以301的使用需要严谨。

原文链接:mp.weixin.qq.com


3 个回复

正序浏览
回复 使用道具 举报
奈斯
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马