浏览器从输入url到呈现发生了什么
1、根据输入的网址解析域名到对应的ip地址,查找顺序:
浏览器缓存、操作系统缓存、路由器缓存、DNS 服务器(记录这域名和ip地址的映射)、根服务器。
2、找到ip地址需要先建立TCP链接
客户端发送 SYN数据包表示请求连接,服务端响应SYN 和 ACK 表示问答,客户端收到后回应一个 ACK数据包表示建立连接成功。
3、发送HTTP请求
完整的请求报文包括请求行(包含请求的方法、url、协议版本)、请求头(浏览器的信息键值对组成)、空行、请求体(请求的数据);
4、服务器处理返回http响应报文
5、(解析DOM)浏览器收到html文件,浏览器会将收到的字节内容、转为字符、token化、转为节点对象,将对象链在一起形成文本对象模型也就是DOM
6、遇到link标签加载css,同时继续解析DOM
7、接收到css文件后通用需要把字节转为字符、token化生产CSSOM
8、如果遇到script标签,下载对应的脚本,CSSOM构建完成后才会执行JS的内容,因为JS即可以操作DOM又可以操作CSSOM,所以需要等js加载完成后再生产渲染树
8、匹配DOM和CSSOM节点,生成渲染树
9、获取节点树的结构、位置、大小、依据盒模型布局
10、将渲染树以像素的形式绘制,呈现网页
11、请求完成后还有一个四次挥手的过程,客户端主动发送FIN 给服务端,服务端收到后先响应ACK等数据全部传输完成再发送FIN,客户端收到后再回应ACK至此,连接断开。
cookie、 session、token 的区别
cookie :用户第一次登录请求时服务端在响应头设置set-cookie,浏览器发送请求并携带cookie,服务器验证cookie正确正常响应。
session: 用户第一次登录请求时服务端创建一个session,并将sessionId设置在响应头set-cookie给客户端,客户端发送请求并携带cookie,服务端通过sessionId找session,验证正确正常响应。
token :用户第一次登录请求时服务端生产token,token中带有用户id,客户方发送请求时将token放在请求头中,服务端获取到token校验通过后正常响应。
三者的区别:
1、cookie 存储在客户端,大小4KB,不够安全;
2、session 存储在服务端 无大小限制 更安全,但是消耗服务器资源;
3、token 都可以存储,体积小,只存了用户id相对安全,需要根据id查找用户信息速度慢;
常见的HTTP请求方法
GET,表示向服务器获取资源
POST,表示向服务器提交信息,通常用于产生新的数据,比如注册
PUT,表示希望修改服务器的数据,通常用于修改
DELETE,表示希望删除服务器的数据
OPTIONS,发生在跨域的预检请求中,表示客户端向服务器申请跨域提交
TRACE,回显服务器收到的请求,主要用于测试和诊断
CONNECT,用于建立连接管道,通常在代理场景中使用,网页中很少用到
常见的HTTP请求头和响应头
常见的请求头:
Content-Type: 请求发送的数据类型,使用最多的是application/json
Cookie: 携带的用户信息
Origin:协议 + 域名 + 端口号
Accept:浏览器可以接受服务器回发的类型 */*
代表浏览器可以处理所有类型
User-Agent:客户端使用的操作系统和浏览器的名称和版本
Connection: 是否保持长连接,设置为keep-alive当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭
常见的响应头:
Access-Control-Allow-Origin: 指定哪些网站可以跨域资源共享
Content-Type:告诉客户端,资源文件的类型
Date:服务端发送资源时的服务器时间
跟缓存相关的响应头:ETag、Expires、Cache-Control
GET 和 POST请求的区别
一、GET不会对服务器资源产生影响,而POST会对服务器资源产生影响;
二、浏览器一般会对GET请求缓存,但很少对POST请求缓存;
三、GET请求的参数 url 可见,而 POST 请求的参数 url 不可见(放在请求体中);
四、GET传送的数据量较小,不能大于2KB(这主要是因为它受约于url长度的限制)
POST的参数可以放在URL上吗
虽然POST方法更加安全,但是并不代表它不能在URL中放参数。
HTTP协议中并没有规定POST方法不能在URL中放参数,只是这种方式不符合HTTP协议的规范,且不安全,所以一般不建议使用这种方式
HTTP和HTTPS协议的区别
一、HTTP协议是超文本传输协议,信息是明文传输;HTTPS协议使用 SSL 或 TLS 来加密数据确保数据传输的安全。
二、HTTP协议使用的端口是80;HTTPS协议使用的端口是443。
三、HTTPS协议需要CA证书,费用较高;而HTTP协议不需要;
HTTP请求报文的是什么样的?
请求报文有4部分组成:
请求行(请求方法、URL、HTTP协议版本)
请求头部(浏览器相关的信息,键值对组成)
空行
请求体(请求携带的数据)
常见的HTTP状态码
http状态码大致分为5类
第一类、1xx 表示提示信息,一般服务器精致向客户端发送这种状态码,见得少;
第二类、2xx 表示请求已经被服务器接收、理解;
200 OK 请求成功
第三类、3xx 重定向,表示需要客户端进一步操作;
301 Moved Permanently 永久性重定向,该状态码表示请求的资源已被分配了新的 URI
302 Found 该状态码表示请求的资源已被临时分配了新的 URI
304 Not Modified 请求资源未修改,使用上次缓存
第四类、4xx 请求错误,通过是客户端错误
400 Bad Request,该状态码表示请求报文中存在语法错误
401 Unauthorized 需要有通过 HTTP 认证
403 Forbidden 该状态码表明对请求资源的访问被服务器拒绝了
404 Not Found 该状态码表明服务器上无法找到请求的资源
第五类、5xx 服务器错误
500 Internal Server Error 该状态码表明服务器端在执行请求时发生了错误
503 Service Unavailable 该状态码表明服务器暂时处于超负载或正在进行停机维护
504 Gateway timeout 代表网关超时是指服务器作为网关或代理,但是没有及时从上游服务器收到请求
http1.0 和 http1.1 的区别
1、长连接,http1.0 默认使用非持久连接(每次请求响应完成后TCP连接就断开,继续请求需要重新建立连接每次都需要经过三次握手四次挥手),而 http1.1 默认开启Connection: keep-alive使用持久连接(响应后无需重新连接可继续发送请求)
2、管道机制,HTTP/1.0不支持请求管道化(同一个TCP连接请求上个请求需要服务端响应后客户端才能继续发送下个请求),HTTP/1.1支持请求管道化(允许客户端同时发送多个请求,服务端按照顺序响应;但是如果前面的请求处理的特别慢会造成队头阻塞)
3、缓存策略,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略,例如Entity tag,If-Unmodified-Since,If-Match,If-None-Match等更多可供选择的缓存头来控制缓存策略
http1.1 和 2.0 的区别
1、服务器推送: HTTP/2 允许服务器未经请求,主动向客户端发送资源
2、二进制协议:在 HTTP/1.1 版中,报文的头信息必须是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧",可以分为头信息帧和数据帧(使用二进制传输数据包更小解析开销更低)
3、头信息压缩机制:由于 HTTP 1.1协议不带状态,每次请求都必须附上所有头信息,但是每次请求很多字段都是重复的,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了
4、数据流: HTTP/2 使用了数据流的概念,因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的请求。因此,必须要对数据包做标记,指出它属于哪个请求。HTTP/2 将每个请求或回应的所有数据包,称为一个数据流。每个数据流都有一个独一无二的编号。数据包发送时,都必须标记数据流 ID ,用来区分它属于哪个数据流
5、多路复用: HTTP/2 实现了多路复用,HTTP/2 仍然复用 TCP 连接,但是在一个连接里,客户端和服务器都可以同时发送多个请求或回应,而且不用按照顺序一一发送,这样就避免了"队头堵塞"的问题
前端缓存说下
我们常说的前端缓存是HTTP缓存,又分为强缓存和协商缓存;
先说下强缓存,是指客户端第一次请求的时候服务端会在响应头中放入expires 或者 cache-control:max-age 字段设置资源新鲜的时间,expires和cache-control:max-age的区别在于 Expires 是http1.0的产物,保存的是一个服务端的时间,但实际对比的是客户端时间,可能会存在时间差;Cache-Control是http1.1的产物,两者同时存在的话,Cache-Control优先级高于Expires;当我们再次请求的时候,浏览器会先自己判断,如果在有效期内,则直接使用缓存,不会发起请求;
第二种是协商缓存,协商缓存每一次发起请求都不会再去询问浏览器的缓存情况,而是直接向服务端去确认该资源是否过期。协商缓存依赖于服务端和浏览器之间的通信,通常客户端第一次请求的时候服务端会在响应头中放入cache-control:no-cache 表示资源被缓存但立即失效,下次会发起请求验证资源是否过期;同时在响应头添加Last-Modified 最后更新日期;浏览器在下次请求时会自动带入If-Modified-Since请求头为上次请求服务端返回的资源更新日期,服务端会对比自己的日期和请求头中带来的日期,如果判断自上次请求后资源未修改,则直接返回304,重定向到浏览器缓存,否则重新返回数据。
但是根据文件最后修改时间判断有个弊端,就是文件被编辑,但实际内容未发生变化,这种情况我们预期中是使用缓存,而实际上会被当做新资源引发一次完整的响应;
所有我们会使用Etag 作为 Last-Modified 的补充,Etag
是由服务器为每个资源生成的唯一的标识字符串,这个标识字符串是基于文件内容编码的,只要文件内容不同,它们对应的 Etag 就是不同的。
在响应头中添加,Etag
后下次请求时请求一个值相同的、名为 if-None-Match 的字符串供服务端比对,他能更精准的感知文件的变化,但是Etag 的生成过程需要服务器额外付出开销,会影响服务端的性能,所以我们需要权衡;
在设置缓存策略是,我们需要根据实际情况决定,当我们的资源不可复用是,直接将Cache-Control 设置 no-store,拒绝一切形式的缓存;
如果需要每次向服务器进行确认,那么设置协商缓存,对于几乎不怎么变更的资源可以设置强缓存;
浏览器缓存是存到哪里呢
内存、磁盘
设置缓存是否过期怎么判断
1、如果是强缓存,浏览器会将上次请求时间和max-age、expires绝对值,以及当前时间对比;
2、如果是协商缓存,服务端通过客户端记录的If-Modified-Since和自己记录的Last-Modified字段对比;
webpack 常用的配置
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // 用于访问内置插件
module.exports = {
// 指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始
entry: './path/to/my/entry/file.js',
// 告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。
output: {
filename: 'my-first-webpack.bundle.js',
},
// webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
// 选择 development, production 或 none 之中的一个
mode: 'production',
// 插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })], /
};
axios 常用的配置
baseURL:将自动加在 url
前面,除非 url
是一个绝对 URL
timeout :指定请求超时的毫秒数,如果请求话费了超过 timeout
的时间,请求将被中断
headers:是即将被发送的自定义请求头
method:是创建请求时使用的方法
params:是即将与请求一起发送的 URL 参数
data:是作为请求主体被发送的数据,只适用于这些请求方法 'PUT', 'POST'
ransformRequest:允许在向服务器发送前,修改请求数据
transformResponse :在传递给 then/catch 前,允许修改响应数据
withCredentials`:表示跨域请求时是否需要使用凭证
proxy:定义代理服务器的主机名称和端口
axios.interceptors.request.use:添加请求拦截器,在请求发送之前统一判断和处理
axios.interceptors.response.use: 统一处理请求成功和错误的情况
什么是事件委托
事件委托也叫事件代理,利用的是事件冒泡机制,通过指定一个事件处理程序来管理某一类型的所有事件的方法。
例如为ul 中所有的li 绑定一个点击事件,那么直接绑定在ul上即可;
为什么使用CDN 会更快(了解)?
没有使用CDN的情况下,用户从浏览器输入地址,依次经过浏览器缓存、操作系统缓存(如本地host文件)、域名解析服务器、根域名解析服务器、顶级域名服务器直到找到对应的ip地址返回给用户,用户向该地址发起请求;
使用了CDN的情况下,用户在浏览器中输入要访问的域名,浏览器向DNS服务器请求对域名进行解析。由于CDN对域名解析进行了调整,DNS服务器会最终将域名的解析权交给CNAME指向的CDN专用DNS服务器。
1、CDN的DNS服务器将CDN的负载均衡设备IP地址返回给用户。
2、用户向CDN的负载均衡设备发起内容URL访问请求。
3、CDN负载均衡设备会为用户选择一台合适的缓存服务器提供服务。选择的依据包括:根据用户IP地址,判断哪一台服务器距离用户最近;根据用户所请求的URL中携带的内容名称,判断哪一台服务器上有用户所需内容;查询各个服务器的负载情况,判断哪一台服务器的负载较小。基于以上这些依据的综合分析之后,负载均衡设置会把缓存服务器的IP地址返回给用户。
4、用户向缓存服务器发出请求。
5、缓存服务器响应用户请求,将用户所需内容传送到用户。
浏览器是如何知道什么域名应该交给CND专用的DNS服务器(了解)?
1、DNS查询:使用nslookup或者dig等工具查询网站的域名解析结果。如果返回的IP地址与原始主机的IP地址不一致,那么很有可能该网站使用了CDN。
2、响应头:使用浏览器的开发者工具,查看网站的响应头信息。如果响应头中包含类似于"X-Cache","X-CDN"或者"Cache-Control"等字段,那么该网站可能使用了CDN。
3、网络请求路径:通过浏览器的开发者工具,查看网站请求的静态资源(例如图片、CSS、JavaScript等)的URL路径。如果路径中包含类似于"cdn"或者"static"等关键字,那么很有可能该网站使用了CDN。
使用CDN有什么好处?
① 减少网络延迟:CDN在全球各地建立了分布式的服务器节点,将网站的内容缓存到离用户最近的节点。当用户访问网站时,CDN会自动将内容传送到最近的服务器节点,这样可以减少数据在全球范围内传输所需的时间,从而减少网络延迟。
② 节省带宽:由于CDN可以缓存网站的内容,因此当用户访问网站时,CDN会从最近的服务器节点提供内容,而不是从源服务器上提取。这可以减少源服务器的负载,从而节省带宽和服务器资源。
③ 提高网站可用性:当源服务器发生故障或停机时,CDN可以自动将流量重定向到其他可用的服务器节点,从而确保网站的可用性。