关于浏览器的相关问题

浏览器缓存

优点

  • 缓存可以帮助我们做性能优化,可以显著减少网络传输所带来的损耗
  • 减少服务器负担,提升网站性能
  • 减少不必要的数据传输,节省宽带

缺点

  • 如果资源有更改但是客户端更新不及时,造成用户获取信息滞后

强缓存

强缓存就是向浏览器缓存查找该请求的结果,根据该结果的缓存规则决定是否使用该缓存

强缓存存在三种情况

  • 不存在该请求的缓存结果和缓存标识,强缓存失效,直接向服务器发起请求
  • 存在该请求的缓存和缓存标识,但是结果已经失效,强缓存失效,采用协商缓存,携带该缓存的标识向服务器发起请求
  • 存在该请求的缓存结果和缓存标识,结果没有失效,强缓存生效直接返回该缓存结果

强缓存的缓存规则

服务器端在response.header对文件做缓存配置,缓存类型、缓存时间等

Expires设置缓存过期时间 (cache-control优先级比expires高)

​ Expires设置缓存时间会存在客户端和服务器端时间存在误差的问题,强缓存会直接失效

respone header 的cache-control,常见的设置是

  • max-age 缓存的时间
  • public 客户端和服务器端都可以缓存
  • private 只有客户端可以缓存
  • no-cache 跳过设置强缓存
  • no-store 客户端和服务器端都不缓存

协商缓存

当强缓存失效后,浏览器携带缓存标识想服务器发起请求,由服务器根据缓存标识决定是否使用缓存。

协商缓存存在两种情况

  • 协商缓存生效,该请求的资源没有更新返回304
  • 协商缓存失效,该请求的资源更新返回200和新的请求结果

协商缓存的标识也会在响应报文的http请求头和请求结果一起返回给浏览器,控制协商缓存的字段有

Last-Modified/If-Modified-Since和Etag / If-None-Match,其中Etag/If-None-Match优先级比其他几个高

Last-Modified / If-Modified-Since

  • Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间
  • If-Modified-Since则是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间,如果服务器资源修时间大于此值表示资源有更新,返回200和更新的资源,如果小于此值,表示资源没有更新返回304,继续使用浏览器中的缓存。

Etag / If-None-Match

  • Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)
  • If-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。把此值与Etag作对比,一致返回304,资源没有更新,否则不一致返回200和更新的资源,资源更新

总结

强缓存优先于协商缓存,但是当强缓存失效则进行协商缓存,协商缓存是由服务器决定是否使用缓存,如果协商缓存也失效那么重新请求获取结果然后在存在浏览器中,协商缓存生效服务器返回304,继续使用缓存。

跨域的解决方法

  • jsonp 在html中通过相应的标签去请求资源(script、img等)但是只能实现get请求

  • iframe标签跨域

  • postMessage跨域 h5中新增的API

    a.html
    window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
    b.html
     window.addEventListener('message', function(e) {
            alert('data from domain1 ---> ' + e.data);
    
            var data = JSON.parse(e.data);
            if (data) {
                data.number = 16;
    
                // 处理后再发回domain1
                window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
            }
        }, false);
    
  • CORS跨域 在服务器设置 Access-Control-Allow-Origin 设置为*时表示该资源谁都可以使用

    response.setHeader("Access-Control-Allow-Origin", "http://localhost:9106");
    
  • 服务器反向代理

      location /apis {
        rewrite  ^.+apis/?(.*)$ /$1 break;
        include  uwsgi_params;
           proxy_pass   http://localhost:1894;
         }
    
  • websocket socket.io跨域

    ​ 前端

    <div>user input:<input type="text"></div>
    <script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>
    <script>
    var socket = io('http://www.domain2.com:8080');
    
    // 连接成功处理
    socket.on('connect', function() {
        // 监听服务端消息
        socket.on('message', function(msg) {
            console.log('data from server: ---> ' + msg); 
        });
    
        // 监听服务端关闭
        socket.on('disconnect', function() { 
            console.log('Server socket has closed.'); 
        });
    });
    
    document.getElementsByTagName('input')[0].onblur = function() {
        socket.send(this.value);
    };
    </script>
    

    ​ nodejs 后台

    var http = require('http');
    var socket = require('socket.io');
    
    // 启http服务
    var server = http.createServer(function(req, res) {
        res.writeHead(200, {
            'Content-type': 'text/html'
        });
        res.end();
    });
    
    server.listen('8080');
    console.log('Server is running at port 8080...');
    
    // 监听socket连接
    socket.listen(server).on('connection', function(client) {
        // 接收信息
        client.on('message', function(msg) {
            client.send('hello:' + msg);
            console.log('data from client: ---> ' + msg);
        });
    
        // 断开处理
        client.on('disconnect', function() {
            console.log('Client socket has closed.'); 
        });
    });
    
  • vue和react中跨域

    vue在vue.config.js中的devServer中配置

    devServer: {
        proxy: {
          '/wxapp': {
            target: 'https://api.smzdm.com',
            changeOrigin: true
          },
          '/home': {
            target: 'https://api.smzdm.com/v1',
            changeOrigin: true
          },
          '/v1':{
            target: 'https://api.smzdm.com',
            changeOrigin:true
          }
        }
    

    react在webpack.config.js中的devServer中配置

    devServer: {
        contentBase: './dist',
        port: 8080,
        historyApiFallback: true,
        proxy: {
          '/api': {
            target: 'http://localhost:9000',
            pathRewrite: { '^/api': '' },
          },
        },
      }
    
  • 服务器中间件代理

    var express = require('express');
    var proxy = require('http-proxy-middleware');
    var app = express();
    
    app.use('/', proxy({
        // 代理跨域目标接口
        target: 'http://www.domain2.com:8080',
        changeOrigin: true,
    
        // 修改响应头信息,实现跨域并允许带cookie
        onProxyRes: function(proxyRes, req, res) {
            res.header('Access-Control-Allow-Origin', 'http://www.domain1.com');
            res.header('Access-Control-Allow-Credentials', 'true');
        },
    
        // 修改响应信息中的cookie域名
        cookieDomainRewrite: 'www.domain1.com'  // 可以为false,表示不修改
    }));
    
    app.listen(3000);
    console.log('Proxy server is listen at port 3000...');
    

    线程和进程

    https://www.zhihu.com/question/25532384

    ​ 进程和线程都是一个时间段的描述,是CPU工作时间的描述。是运行中的程序指令的一种描述

    ​ 进程和线程都可以并发执行

    • 线程 cpu调度的最小单位

      • 线程在进程下进行
      • 一个进程包含多个线程
      • 同一进程下的不同线程间数据容易共享
      • 一个线程挂掉会导致整个进程挂掉
    • 进程 资源分配的最小单位

      • 不同进程间数据很难共享
      • 进程间不会相互影响
      • 进程更加消耗计算机资源

堆、栈、队列

  • 堆是在程序运行时申请的内存空间,动态分配内存

  • 栈只是一种使用堆的方法,是一种先进后出的数据结构,删除与加入都在栈顶进行

  • 队列

    队列先进先出,在队头作删除,在队尾做插入

url从输入到渲染页面的过程

  • 浏览器构建HTTP Request请求,DNS解析URL地址、生成Http请求报文、构建Tcp连接、使用IP协议选择传输路线
  • 请求通过网络传输到服务器,(通过集线器、交换机、路由器等)
  • 服务器构建HttpResponse响应,响应客户端的请求,将响应体的数据返回给客户端
  • 浏览器开始页面渲染,解析HTML、CSS、JS生成RenderTree渲染页面

浏览器渲染页面解析过程

根据html文件构建DOM树和CSSOM树,构建DOM树期间,如果遇到JS会阻塞DOM树和CSSOM树的构建,优先加载JS,加载完JS后在继续构建DOM树和CSSOM树。如果JS操作了DOM根据操作的大小浏览器对页面进行重绘或重排。

  1. 解析html:按顺序解析,并在解析的过程中构建DOM树
  2. 构建dom树:和步骤1同步进行,一边解析一边构建
  3. 构建呈现renderTree 将dom树和css树结合
  4. 布局 计算renderTree节点的大小和位置,递归进行
  5. 绘制 布局完成后,将renderTree绘制在屏幕上

回流和重绘

回流reflow 当页面中的一部分因为尺寸、布局、隐藏等改变重新构建成为回流

重绘 当页面中的一部分元素需要更新属性,这个只会影响到外观、风格而不会影响到布局等操作就是重绘。

浏览器事件循环机制

js中的任务分为宏任务和微任务,都采用先进先出的执行策略,同步任务都在宏任务中。

宏任务主要有:script(整体代码)、setTimeout、setInterval、I/O、UI 交互事件、postMessage、MessageChannel、setImmediate(Node.js 环境)。

微任务主要有:Promise.then、 MutationObserver、 process.nextTick(Node.js 环境)。

具体步骤:

  • 从宏任务头部取出一个任务执行
  • 执行过程中若遇到微任务则将其加到微任务队列中
  • 宏任务执行完毕后,微任务队列中如果存在则挨个执行
  • 微任务执行完后回到宏任务继续执行

Nodej中的eventloop

  • timers 执行setTimeout和setInterval中到期的callback
  • pending callback 上一轮中少数的callback会放在这一阶段执行
  • idle,prepare 仅在内部使用
  • poll 最重要的阶段,执行pending callback,在适当的情况下会阻塞在这个阶段
  • check 执行setImmediate(setImmediate()是将事件插入到事件队列尾部,主线程和事件队列的函数执行完成后立即执行setImmediate指定的回调函数)的callback
  • close callbacks 执行close事件的callback

post和get的区别

  • get在浏览器回退时是无害的,post会再次提交请求。

  • get请求还会被浏览器主动cache,post不会除非手动设置

  • get请求只能进行url编码,而post支持多种编码方式

    1. Content-Type:application/x-www-form-urlencoded 原生表单
    2. Content-Type:application/json 参数已json形式放到消息体中 编码utf-8
    3. Content-Type:text/xml 参数以string类型即可
    4. multipart/form-data 表单上传文件时,form表单的enctype属性
  • get请求的参数会保留在浏览器历史中,post不会

  • get请求url传参有长度限制,并且只接受ASCII字符,post没有限制

  • get参数暴露在url上 post放在request body中

  • get产生一个tcp数据包,pos它产生两个tcp数据包

    ​ 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

    ​ 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

    并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

移动端1px边框解决

  • 使用border-image实现

    div
    {
    	-moz-border-image:url(/i/border.png) 30 30 stretch; /* Old Firefox */
    	-webkit-border-image:url(border.png) 30 30 stretch; /* Safari 5 */
    	-o-border-image:url(border.png) 30 30 stretch; /* Opera */
    	border-image:url(border.png) 30 30 stretch;
    }
    
    
  • background-image

    .background-image-1px {
    	background: url(../img/line.png) repeat-x left bottom;
    	-webkit-background-size: 100% 1px; background-size: 100% 1px;
    }
    
    
  • 伪元素+transfrom

    ​ 构建一个伪元素border为1px,在以transform缩放到50%

/*设计稿是750,采用1:100的比例,font-size为100*(100vw/750) */
.border-1px {
    position: relative;
}
@media screen and (-webkit-min-device-pixel-ratio: 2) {
    .border-1px:before {
        content: " ";
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 1px;
        border-top: 1px solid #D9D9D9;
        color: #D9D9D9;
        -webkit-transform-origin: 0 0;
        transform-origin: 0 0;
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
}

原文链接:https://blog.csdn.net/yexudengzhidao/article/details/98480173
  • js计算rem基准值和viewport缩放值

    ​ 用JS根据屏幕尺寸和dpr精确地设置不同屏幕所应有的rem基准值和initial-scale缩放值

    /* 设计稿是750,采用1:100的比例,font-size为100 * (docEl.clientWidth * dpr / 750) */
    var dpr, rem, scale;
    var docEl = document.documentElement;
    var fontEl = document.createElement('style');
    var metaEl = document.querySelector('meta[name="viewport"]');
    dpr = window.devicePixelRatio || 1;
    rem = 100 * (docEl.clientWidth * dpr / 750);
    scale = 1 / dpr;
    // 设置viewport,进行缩放,达到高清效果
    metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');
    // 设置data-dpr属性,留作的css hack之用,解决图片模糊问题和1px细线问题
    docEl.setAttribute('data-dpr', dpr);
    // 动态写入样式
    docEl.firstElementChild.appendChild(fontEl);
    fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}';
    
    

解决input在ios有阴影问题

input{
    -webkit-appearance: none;
}

布局的几种方式

  • 文档布局 普通流 从左到右,从上到下
  • 浮动布局
  • 定位布局
  • 流式布局 用百分比做单位
  • 弹性布局 flex em rem做单位
  • 自适应布局 根据媒体查询
  • 响应式布局 流式布局和自适应布局设计理念的融合。即:创建多个流体式布局,分别对应一个屏幕分辨率范围。响应式几乎已经成为优秀页面布局的标准,每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变媒体查询+流式布局

Cookie

服务器端可以通过响应头中的set-Cookie设置cookie发送给客户端。

Cookie的有效期可以通过Expire和Max-Age设置

  • Expire就是过期时间
  • Max-Age用的是一段时间间隔,单位是秒,从浏览器接收到报文开始计算

作用域

关于cookie作用域有两个属性:Domain和path

Domain

domain表示cookie所在的域,默认为请求的地址,如网址为www.study.com/study,那么domain默认为www.study.com。而跨域访问,如域A为t1.study.com,域B为t2.study.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.study.com;如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为t2.study.com。注意:一般在域名前是需要加一个".“的,如"domain=.study.com”。

path

path表示cookie所在的目录,默认属性为 / ,就是根目录,表示该域名下的任何路径都可以使用cookie。

安全

如果带有Secure属性表示只能通过HTTPS传输cookie,

带有httpOnly属性表示只能通过HTTP协议传输,并且不能通过JS访问cookie,这一样可以预防XSS攻击。

对于CSRF攻击,可以使用SameSite属性,有三个值:

  • Strict模式,浏览器禁止第三方请求携带Cookie,比如请求sanyuan.com网站只能在sanyuan.com域名当中请求才能携带 Cookie,在其他网站请求都不能
  • Lax模式 ,只能在get方法提交表单或者a标签发送get请求的情况下才可以携带Cookie,其他情况都不可以
  • None模式, 这是默认模式,此模式下请求会自动携带Cookie

缺点

  • 容量缺陷,cookie携带数据大小只有4kb
  • 性能缺陷,cookie紧跟在域名后面,不管域名下的某一个地址是否需要cookie,请求都会携带完整的cookie。随着请求增多,会造成巨大性能浪费,请求携带大量不需要的内容。但是可以通过Domain和path指定作用域来解决。
  • 安全缺陷, cookie是以纯文本的形式在浏览器和服务器中传递的,很容易被截取然后进行篡改,在cookie有效期内重新发送给服务器跟危险,而且在httpOnly为false的情况下Cookie能够被JS直接获取。

打开谷歌浏览器有四个进程

一个网络进程,一个浏览器进程,一个GPU进程,一个渲染进程

cookie和session的区别

  • 存储位置 存储位置不同cookie存放在客户端浏览器,session存放在服务器上
  • 容量不同 耽搁cookie保存数据最大4kb,一个站点最多保存20个cookie,而session没有上限,但是要考虑服务器的性能
  • 存储方式 cookie只能保管ascii字符串,需要通过编码方式存储为unicode字符或二进制数据。session能储存任何类型的数据
  • 有效期不同 cookie可以设置属性控制cookie的有效期,session过期时间默认为-1,关闭窗口就失效。
  • 跨域 cookie支持跨域名访问,session不支持跨域名访问

UDP和TCP

TCP

TCP(传输控制协议)是面向连接的协议,在收发数据前必须和对方建立可靠的连接,一个tcp连接必须经过三次对话才能建立起来,经过三次“对话”才能正式发送数据。断开连接要进行四次。

优点

tcp提供可靠、稳定的服务,通过tcp连接传送的数据,无差错,不丢失,不重复,且按序到达。连接之前会有三次握手建立连接,数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完之后还会断开连接节约资源。通过校验,重传控制,序号标识,确认应答实现可靠传输,当丢包时的重发控制可以对次序乱掉的分包进行顺序控制。

缺点

传输慢、效率低、占用系统资源高,容易被攻击,在建立连接之前三次握手消耗时间,连接还会占用系统的cpu,内存等资源。确认机制和三次握手容易被人利用,实现DOS等攻击。TCP每条连接只能是点对点的。采用复杂的拥塞控制算法。

UDP

UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,使用UDP协议时不需要建立连接,只需要知道对方IP地址和端口号就可以直接发送数据包,但是能不能到达不知道。一台服务机可以同时向多个客户机传输相同消息。DHCP就是基于UDP协议,比如直播、实时游戏、物联网等

优点

传输速度快,比tcp安全,没有tcp的握手、确认等机制,UDP是无状态的传输协议,所以传输速度很快,工作效率比TCP高,适用于高速传输和实时性较高的通信或广播通信,而且被攻击的漏洞就少一点。UDP支持一对一,一对多,多对一和多对多的交互通信。

缺点

不可靠,不稳定,当网络质量不好时容易丢包

TCP和UDP的区别

  • TCP面向连接,UDP是无连接的
  • TCP保证数据的正确性,提供可靠的服务,数据无差错,不重复,不丢失,按序到达;UDP尽最大努力交付单数不保证可靠交付
  • UDP有较好的实时性,工作效率比TCP高,使用与高速传输和实时性较高的通信或广播
  • TCP对系统资源要求较多,UDP对系统资源要求较少
  • TCP面向字节流,UDP是基于数据报

一次js请求一般情况下有哪些地方会有缓存处理?

有 cdn缓存,dns缓存,浏览器缓存,服务器缓存 。

http和https

http

超文本传输协议,基于TCP/IP通信洗衣来传输数据,属于应用层面向对象。

以明文形式传递信息(在url上)

  • 简单快速,只需传送请求方式和路径
  • 灵活 允许传输任意类型的数据对象,Content-Type加标记
  • 无连接 每次连接只处理一个请求 ,服务器处理完请求收到客户端应答断开连接
  • 无状态 对于书事务处理没有记忆能力,缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大

https

安全超文本传输协议

http下加入SSL层,依靠证书验证服务器的身份

HTTPS和HTTP的主要区别:

https协议需要到ca申请证书,一般免费证书很少,需要交费。
http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。
http的连接很简单,是无状态的。
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 要比http协议安全。

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

吴彦祖敲代码

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值