bug之所措

bug之所措 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑

微信踩坑文章被隐藏了,我也不知道为什么
版本2021-1-13 16:18
htt啦啦ps://segm啦啦entfault.com/a/1190000啦啦021470685/ed啦啦it

个人动态

bug之所措 发布了文章 · 2020-09-29

【没有实践系列】浏览器的强缓存和协商缓存

一、前言

先记录从其他文章得到经验,看看以后有没机会用上

二、缓存是前端还是后端设置?

后端设置,全部都是在响应头,response header这个里面设置属性

三、类型

1.强缓存

设置cahe-control,比如像这样
image.png

Cache-Control 的几个取值含义:

private: 仅浏览器可以缓存

public: 浏览器和代理服务器都可以缓存(对于private和public,前端可以认为一样,不用深究)

max-age=xxx 过期时间(重要)

no-cache 不进行强缓存(重要)

no-store 不强缓存,也不协商缓存(下一个介绍的类型),基本不用,缓存越多才越好呢

规则可以设置多个,像
cahe-controlmaxage=31536000,public,immutable

下面流程单独指强缓存,实际上是先强缓存后协商缓存的流程,要注意

  1. 用户请求一张图片
  2. 浏览器查找缓存表,
  • 没有,请求服务器,服务器返回资源(状态码200),把它存到缓存表
  • 有,再读max-age有没有过期

    • 没有过期,拿缓存返回(状态码200)
    • 过期了,请求服务器,服务器返回资源(状态码200),把它存到缓存表

虽然在network看起来好像都是请求了接口,但是要注意其实有上面判断的,可以看这里
image.png
看到后面那段话没,来自内存缓存。

2.协商缓存

当强缓存失效,(设置了no-cache或者max-age过期了)就会走这个

设置两个属性ETagLast-Modified
image.png

ETag:每个文件有一个,改动文件了就变了,可以看似md5
Last-Modified:文件的修改时间

下面流程单独指协商缓存,实际上是先强缓存后协商缓存的流程,要注意

  1. 第一次请求资源,在response header都会有上面两个属性返回,浏览器会把这些存到缓存
  2. 下次请求同一个资源时,在request header会把这两个值带过去,并且ETag这个key会换了一个名字If-None-Match

image.png

  1. 服务端接受请求,对比这两个值
  • 没有过期,状态码304,直接拿缓存的
  • 过期了,服务器返回新资源(状态码200),当然也有新的etag和last-modified,浏览器缓存表更新

这里注意,协商缓存无论是不是命中,都请求了接口,这个搞清楚,只是命中了,响应很快,没命中,就是正常的响应速度

四、完整流程

缓存命中是先走强缓存走协商缓存的,看图
image.png

五、其他补充

用户操作对缓存影响
image.png

关于cdn
个人理解,cdn只是代替了你的原始服务器,优点就是它的响应更快,然后强缓存和协商缓存还是依旧有执行判断的。

非常感谢以下大佬
浏览器缓存
用了CDN缓存,就会跳过强缓存和协商缓存吗?

查看原文

赞 1 收藏 1 评论 0

bug之所措 赞了回答 · 2020-09-28

解决用了CDN缓存,就会跳过强缓存和协商缓存吗?

附一张图
https://segmentfault.com/img/...
clipboard.png

强缓存是直接使用本地缓存(根据Expires或者Cache-Control来判断),命中后直接从本地返回。没命中的话,带着Last-Modified或Etag和服务器确认,在确认的网络传输过程中可能会经过CDN服务器,CDN服务器如果本地有缓存,可以根据资源情况返回304(资源有效)或者200(客户端资源无效,返回CDN服务器本地资源),这个和终端服务器的逻辑是一致的。

Cache-Control中有两个属性和CDN服务器有关,

  • public,代表可以被所有终端缓存,包括CDN服务器
  • private,只能被终端浏览器缓存,CDN服务器等中继服务器不能缓存。

这3个概念并不冲突,强缓存是本地缓存,有效期内直接使用,失效后要去服务器验证下(就是你说的协商缓存),协商过程中可能经过CDN服务器,就出来了CDN缓存。所以无论你开不开CDN缓存,都不影响强缓存和协商缓存的逻辑

关注 4 回答 2

bug之所措 发布了文章 · 2020-09-22

关于普通函数,箭头函数里this指向的分析见解

内容大概

  • 普通函数的this
  • 箭头函数的this

普通函数

1.结论

先说结论,普通函数的this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象,并且是最近的那个

2.分析

例子1:

function a(){ 
    var user = "函数内部a";
    console.log(this.user); //undefined
    console.log(this); //Window
}
a();

我们知道像这种调用方式,都是window调用,所以输出如上,验证一下

例子2:

var user = "window的a";
function a(){ 
    var user = "函数内部a";
    console.log(this.user); //window的a
    console.log(this); //Window
}
a(); 

a()前面没有东西默认window.a(),调用方是window,所以此时输出“window的a”

例子3:

var o = {
    user:"追梦子",
    fn:function(){
        console.log(this.user);  //追梦子
 }
}
o.fn();

这里的this指向的是对象o,因为你调用这个fn是通过o.fn()执行的,那自然指向就是对象o,这里再次强调一点,this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,一定要搞清楚这个。

例子4:

var user = "window追梦子"
var o = {
    user:"追梦子",
    fn:function(){
        console.log(this.user);  //追梦子
 }
}
window.o.fn();

这里虽然最外层是window调用,但是输出的this是对象o,这跟我上面说的结论一样,this的最终指向的是那个调用它的对象,并且是最近的那个

例子5:

var o = {
    user:"追梦子",
    fn:function(){
        console.log(this) // o
        setTimeout(function(){
            console.log(this);  //window
        },1000)
        
 }
}
o.fn();

fn被对象o触发,所以输出o,定时器和延时器塞队列,最后是由window触发的,所以输出window

箭头函数(敲黑板,重点)

1.结论

  • 在定义的时候就确认了this的指向,跟普通函数在使用的时候确认是完全不同
  • 作用域总是指向当前作用域的上一个,上一个,上一个(很重要说3遍)!
  • 当前作用域的上一个指向的对象,就是this的指向

PS:JS的作用域一般指的是函数作用域,全局作用域,使用let那种块级作用域不算

2.分析

例子1:

var b=11;
var obj={
 b:22,
 say:()=>{
 console.log(this.b);
}
}
obj.say();//输出的值为11

say是箭头函数,当前作用域的上一个作用域就是全局,而全局指的是window,所以输出11

例子2:

var b=11;
var obj={
 b:22,
 say:function(){
  return () => {
     console.log(this.b);
  }
 }
}
obj.say()();//输出的值为22

say里面return的那个是箭头函数,当前作用域的上一个作用域是say函数,然后say函数作用域指的是obj,所以输出22

例子3:

var str = 'window';  
 
const obj = {
    str:'obj',
    fn: ()=>{
    console.log(this.str);    
    },
    fn2: function(){
    console.log(this.str)
    return {
        str: 'newObj',
        fn: ()=>{
        console.log(this.str);    
        }    
    }
    }
}
 
obj.newFn = ()=>{
    console.log(this.str);    
}
 
obj.fn(); //window
obj.newFn(); //window
obj.fn2().fn(); //输出obj,obj
  1. fn上一级是全局,所以是window
  2. newFn是在外面定义的,不过解析也是跟fn一样
  3. fn2是obj触发,所以输出obj,fn2里面返回了一个对象,对象里面有一个fn箭头函数,这个fn的上一级作用域是fn2(这里注意不要被newObj迷惑)fn2指向的对象是obj,所以输出还是obj

例子4:

var obj = {
  str:'obj',
  fn: function(){
   return {
    str: 'inlineObj',
    fn1: function(){
     console.log(this.str); 
     return ()=>{
      console.log(this.str); 
     }
    },
    fn2: ()=>{
     console.log(this.str); 
    }
   }
  }
 }
 
 obj.fn().fn1()(); //输出inlineObj,inlineObj
 obj.fn().fn2(); //输出obj

1.obj.fn()这里注意已经返回了一个对象,所以触发fn1的时候,输出inlineObj,fn1里面return一个箭头函数,上一级作用域是fn1,fn1指向return的那个{},所以输出也是inlineObj
2.fn2的上一级作用域是fn,fn指向obj,所以输出obj

更改this的指向

普通函数可以改

var user = "window的a";
function a(){ 
    var user = "函数内部a";
    console.log(this.user);
}
var obj = {
    user:'obj的a'
}
a() //window的a
a.call(obj) //obj的a

箭头函数不可以改

var obj = {
  str:'obj',
  fn: function(){
    console.log(this.str)
   },
  fn2: function(){
    return () => {
        console.log(this.str)
    }
    
  }
}
var obj2 = {
    str:'obj2'
}
obj.fn()  //obj
obj.fn.call(obj2) //obj2
obj.fn2()() //obj
obj.fn2().call(obj2) //obj

可以看到,箭头函数就算用了call换了this指向,输出还是当初定义的那个范围

一些比较特别

点击事件

<div id="dianji">点击事件</div>

document.getElementById('dianji').addEventListener('click',function(){
    console.log(this); // 输出dom
 })
document.getElementById('dianji').addEventListener('click',() =>{
    console.log(this); // window
 })

.addEventListener前面是dom,所以普通函数触发的时候输出dom,谁调用输出谁,而箭头函数的上一级作用域是全局,所以输出window

当this碰到return

返回空对象{}

function fn()  
{ 
    this.user = '追梦子'; 
    return {};  
}
new fn().user    //undefined

返回函数

function fn()  
{ 
    this.user = '追梦子'; 
    return function aaa(){};
}
new fn().user    //undefined

返回数字

function fn()  
{ 
    this.user = '追梦子'; 
    return 1;
}
new fn().user  //追梦子

返回null

function fn()  
{ 
    this.user = '追梦子'; 
    return null;
}
new fn().user  //追梦子

上面的列子主要说明
如果返回值是一个引用数据类型(函数,对象都属于object),那么this指向的就是那个返回的对象,如果返回值不是一个对象(基础数据类型,数值,字符串,布尔,null,undefined)那么this还是指向函数的实例。

鸣谢
非常感谢以下几位大佬的文章
彻底理解js中this的指向,不必硬背。
ES6箭头函数的this指向详解
【ES6】两个例子明白箭头函数this指向
ES6中箭头函数中的this指向

查看原文

赞 0 收藏 0 评论 0

bug之所措 赞了回答 · 2020-08-25

解决VUEX如何调用modules里面的mutations

store 后面不需要加 a。除了 state 是分模块的,其他 mutations 和 actions 都不分模块,因此规划的时候要注意不要重名!

关注 5 回答 6

bug之所措 赞了回答 · 2020-08-18

vue实例中template: '<App/>',这样写是什么意思

我刚开始学,看这个东西看了好久,官网文档的描述我不太理解,今天终于算明白了

官网的描述:

模板将会替换挂载的元素。挂载元素的内容都将被忽略

也就是说:template: '<App/>' 表示用<app></app>替换index.html里面的<div id="app"></div>

如果还是不明白,改成这样子就好理解了:
index.html

<div id="myapp">
    <app></app>
</div>

main.js

new Vue({
    el:'#myapp',
    router,
    components:{App}
})

这样写的意思是:实例化一个Vue,挂载到id为myapp的div里面,这个vue实例有个局部组件App

webpack的模板写得这么绕的原因:(个人猜测)

  • 如果像我那样写,dom树多了个不必要的div层
  • 旧的版本应该是可以把实例挂载到body、header元素的,但是新的版本会报错:不要尝试挂载到body元素。

关注 14 回答 6

bug之所措 关注了问题 · 2020-07-19

必应地图的REST服务直接在浏览器打开,为什么接口没有响应,也没报错?

我已经申请了key值了,按道理来说直接在浏览器打开接口应该是可以访问才对啊,跟腾讯位置服务一样,可惜为什么这个必应的就死活访问不了,请问有大佬前辈知道吗,感激不尽!! = =||

image.png
image.png

明明已经换了key值了。

关注 2 回答 1

bug之所措 提出了问题 · 2020-07-17

必应地图的REST服务直接在浏览器打开,为什么接口没有响应,也没报错?

我已经申请了key值了,按道理来说直接在浏览器打开接口应该是可以访问才对啊,跟腾讯位置服务一样,可惜为什么这个必应的就死活访问不了,请问有大佬前辈知道吗,感激不尽!! = =||

image.png
image.png

明明已经换了key值了。

关注 2 回答 1

bug之所措 收藏了问题 · 2020-06-30

flex布局换行元素产生的间隙问题?

在使用flex布局的时候,发现换行的元素不会紧贴着上一排元素,而是产生了一定的间隙:
图片描述

灰色部分是多出来的地方,这是当前页面的代码:

.container{
    display: flex;
    flex-flow: row wrap;
    background: rgb(185, 185, 185);
    height: 10em;       
}
.item{
    flex: 1 20%;
    height: 3em;
    background: rgb(156, 252, 255);
}
.item:nth-child(2n) {
    background: #79afec;
}
<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
</div>

好像是flex布局自动上下平分了空间,请问有没有办法在保证容器和元素高度的情况下让换行的元素紧贴着上一行呢?

bug之所措 赞了回答 · 2020-06-30

解决flex布局换行元素产生的间隙问题?

在大容器上写上
align-content: flex-start
即可;

关注 6 回答 3

bug之所措 赞了回答 · 2020-06-30

解决flex布局换行元素产生的间隙问题?

.container{
    display: flex;
    flex-flow: row wrap;
    background: rgb(185, 185, 185);
    height: 10em;  
    align-content: flex-start;     
}

关注 6 回答 3

认证与成就

  • 获得 65 次点赞
  • 获得 79 枚徽章 获得 2 枚金徽章, 获得 27 枚银徽章, 获得 50 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-10-06
个人主页被 2.6k 人浏览