Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

网络/浏览器面试题 #3

Open
mewcoder opened this issue Mar 12, 2024 · 8 comments
Open

网络/浏览器面试题 #3

mewcoder opened this issue Mar 12, 2024 · 8 comments

Comments

@mewcoder
Copy link
Owner

mewcoder commented Mar 12, 2024

@mewcoder
Copy link
Owner Author

http 头部有哪些

  • 基础

    • Accept | Content-Type 内容类型
    • Accept-Encoding | Content-Encoding 编码方式
    • Connection:Keep-Alive 长连接
    • User-Agent 浏览器信息
    • Host 主机名
    • Referer 来源页面
  • Cookie相关:Cookie | Set-Cookie

  • 缓存相关

  • CORS 相关

@mewcoder
Copy link
Owner Author

mewcoder commented Mar 12, 2024

Cookie

主要用于,会话状态管理,用户跟踪。
缺点:

  • 空间小 4K 限制;网络请求会携带影响性能;

  • 不论请求方式和发起页面, Cookie都会自动携带,导致安全和隐私问题,如 CSRF

  • 可设置有效期(Expires/Max-Age), 不设置关闭浏览器会自动清除

  • Domain/Path 定义了 Cookie 的作用域

  • HttpOnly 限制 JS 访问(document.cookie

  • Secure 标记为只能通过 HTTPS 发送

第三方 Cookie 的问题:

  • SameSite 限制三方 Cookie 在跨站(顶级域名不同)请求时不会被发送,http 不支持,需要同时设置Secure
    • Strict 不允许跨站
    • Lax 允许部分请求,如 alink
    • None 不限制
    • Chrome 80+ 默认是 Lax
  • Chrome 新版本浏览器停用第三方 Cookie
  • Chrome 114 增加了 Cookie 独立分区 新属性,Partitioned, 第三方 cookie 可以用,但跨站不共享;

@mewcoder
Copy link
Owner Author

mewcoder commented Mar 14, 2024

CSRF

跨站请求伪造

攻击者利用 HTTP 请求会自动携带 cookie 的特定,利用用户的登陆状态发送恶意请求。

方法:自动发起 get/post 请求;诱导点击

CSRF 的过程:

  • 用户登录了 a.com ,有了 cookie
  • 黑客引诱用户访问 b.com 网页,偷偷让用户访问了 a.com/api/xxx(干某件事)
  • a.com api 接口收到请求 cookie ,误以为是真实用户的请求,就受理了

防御方法::

  • 验证请求头的 Referer 字段,不为空且在白名单内。js 是无法修改的,浏览器插件和代理可以改。但是 UGC 的网址,用户可以自己插入链接,Referer 又是合法的,get 如果是写操作就会有问题,除了这种,Referer是有效的手段。
  • Origin,和前者一样
  • SameSite 限制 Cookie 在跨站请求时不会被发送;但会导致一些业务不方便,影响业务体验。
  • 加入 CSRF token 验证(最佳实践,更简单)
    • token 放在请求头或请求体 和 cookie 中,后端验证二者一致性;
    • token 不放 cookie,而是放 sessionid , 后端要维护映射表。

https://zhuanlan.zhihu.com/p/522562168

@mewcoder
Copy link
Owner Author

mewcoder commented Mar 14, 2024

DNS 解析过程

DNS(Domain Name System,域名系统)是一个将域名和 IP 地址相互映射的分布式服务

  • 首先会查找缓存缓存:浏览器-操作系统-路由器-本地域名服务器。

  • 客户端发送请求给本地域名服务器,如果没有则继续(递归)

  • 本地域名服务器,向根域名服务器,返回顶级域名服务器地址,然后请求拿到权威域名服务器,最后请求拿到 IP 返回给客户端(迭代)

一般我们向本地 DNS 服务器发送请求的方式就是递归查询,因为我们只需要发出一次请求,然后本地 DNS 服务器返回给我们最终的请求结果。而本地 DNS 服务器向其他域名服务器请求的过程是迭代查询的过程,因为每一次域名服务器只返回单次查询的结果,下一级的查询由本地 DNS 服务器自己进行。

@mewcoder
Copy link
Owner Author

HTTPS 的原理

HTTPS 其实就是 HTTP+TLS 的传输方式,TLS 叫传输层安全,之前叫 SSL(安全套接层)。

因为 HTTP 属于明文传输,可以被截取到。那么就需要对传输报文进行加密,加密方式有两种:非对称和对称。对称就是同一个密钥进行加密解密,非对称就是有一组公私密钥,可以互相加解密。

那么 TLS 是怎么做的呢?

因为非对称加密的效率不高,对 HTTP 报文一般采用对称加密,然后通过非对称加密传输这个会话密钥。

比如客户端生成一个会话密钥通过一个公钥加密,服务端通过私钥解密获得会话密钥,就可以安全地传输报文了。

但是这个公钥不能安全地传输到客户端手里,即使加密也需要对应的密钥进行传输,现在的通过 CA机构 解决这个密钥的信任问题。

  1. 服务端向 CA机构申请一个证书,这个证书,就是用 CA机构的私钥 加密过的 网站的公钥
  2. 然后客户端请求得到这个证书,通过预装在客户端的 CA机构的公钥 进行解密和验证签名,得到这个网站的公钥
  3. 简单的讲,客户端就可以生成一个会话密钥通过网站的公钥加密传输给服务端,服务端通过网站的私钥解密后就得到了这个会话密钥

但是,真实情况不是这个简单流程(RSA),有密钥交换算法,比如 ECDHE,在请求返回证书的过程,服务端和客户端会分别交互两个随机数,然后自个通过协商好的算法参数生成第三个随机数,再通过这个三个随机数生成会话密钥,这个密钥是不需要传输的,两边都知道,之后就可以加密传输了。

@mewcoder
Copy link
Owner Author

mewcoder commented Mar 14, 2024

HTTP2 的特性

  • 二进制帧:
  • 多路复用(并发传输),解决了 http 的队头阻塞问题
  • 头部压缩:HPACK算法压缩头部(静态字典、动态字典和 huffman 编码)
  • 服务器推送

多路复用

  • HTTP/1.1:同⼀时间⼀个 TCP 连接只能处理⼀个请求, 采⽤⼀问⼀答的形式, 上⼀个请求响应后才能处理下⼀个请求。由于浏览器最⼤ TCP 连接数的限制, 所以有了最⼤并发请求数的限制.
  • HTTP/2.0:同域名下所有通信都在单个连接上完成,消除了因多个 TCP 连接⽽带来的延时和内存消耗。单个连接上可以并⾏交错的请求和响应,之间互不干扰。

为什么 HTTP/1.1 不能实现多路复⽤?

  • HTTP/2 是基于⼆进制“帧”的协议,HTTP/1.1 是基于(报文)“⽂本分割”解析的协议。
  • HTTP1.1 的报⽂结构中, 服务器需要不断的读⼊字节,直到遇到换⾏符, 或者说⼀个空⽩⾏. 处理顺序是串⾏的, ⼀个请求和⼀个响应需要通过⼀问⼀答的形式才能对应起来。
  • HTTP2.0 中,有两个⾮常重要的概念,分别是帧(frame)流(stream)。帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。
  • 多路复⽤,就是在⼀个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免 HTTP 旧版本中的队头阻塞问题,极⼤的提⾼传输性能。
  • 但是 TCP 的对头阻塞问题并没有解决

@mewcoder mewcoder changed the title 网络面试题 网络/浏览器面试题 Mar 16, 2024
@mewcoder
Copy link
Owner Author

mewcoder commented Mar 26, 2024

浏览器事件循环机制

JS 是单线程的,同时只能执行一项任务。但浏览器或者Node.js环境中存在着大量的I/O操作(如网络请求、定时任务等),如果同步执行的话就会阻塞,所以就有了异步任务的事件循环机制。

JS 会先执行当前任务,遇到异步任务就放入任务队列中,分为宏任务和微任务,当前宏任务执行完会处理所有的微任务,再从宏任务队列中取一个开始下一个宏任务。

宏任务:script 脚本

  • setTimeout() / setInterval() /requestAnimationFrame() / Node: setImmediate()
    微任务:
  • Promise() / MutationObserver() / queueMicrotask() / Node: process.nextTick()

为什么浏览器定时器不准

  • 如果 setTimeout 存在嵌套调用且超过 5 次,时间间隔被强制设定为至少 4 毫秒
  • 如果当前任务执行时间过久会导致定时器设置的任务被延迟执行。

@mewcoder
Copy link
Owner Author

mewcoder commented Mar 26, 2024

requestAnimationFrame

指定回调函数是在浏览器下一次绘制之前执行,每秒60帧的话,大概是16.6ms 一次,可以用于动画

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant