网络和浏览器相关笔记

本文深入探讨了浏览器的工作原理,包括多进程架构、渲染进程、垃圾回收机制以及JavaScript执行流程。详细阐述了HTTP协议的请求与响应过程,介绍了HTTP状态码、缓存策略以及跨域问题。此外,还讲解了TCP连接的建立与断开,以及TCP与UDP的区别。最后,讨论了网络安全相关的话题,如CSRF、XSS和DDoS攻击及其防御措施。
摘要由CSDN通过智能技术生成
浏览器的多进程
Browser进程:

浏览器的主进程(负责协调、主控),只有一个

作用

  1. 负责浏览器界面显示,与用户交互。如前进,后退等
  2. 负责各个页面的管理,创建和销毁其他进程
  3. 网络资源的管理,下载
第三方插件进程:

每种类型的插件对应一个进程,仅当使用该插件时才创建

GPU进程:

最多一个,用于3D绘制等

浏览器渲染进程

(浏览器内核内部是多线程的):默认每个Tab页面一个进程,也就是我们每个标签页所拥有的进程,互不影响,负责页面渲染,脚本执行,事件处理等。

GUI渲染线程

负责渲染浏览器界面,包括解析HTML、CSS、构建DOM树、Render树、布局与绘制等
当界面需要重绘或由于某种操作引发回流时,该线程就会执行。

JS引擎线程

负责处理执行javascript脚本。等待任务队列的任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS引擎在运行JS程序。

事件触发线程

归属于浏览器,用来控制事件循环。当JS引擎执行代码块如setTimeout时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中
当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。

注意:由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)

定时器触发线程
  • 传说中的setIntervalsetTimeout所在线程
  • 浏览器定时计数器并不是由JavaScript引擎计数的,(因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确)
  • 因此通过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待JS引擎空闲后执行)
  • 注意,W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms。
异步http请求线程
  • 在XMLHttpRequest在连接后是通过浏览器新开一个线程请求
  • 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中。再由JavaScript引擎执行。
垃圾回收

js有自己的一套垃圾回收机制(Garbage Collection)。JavaScript的解释器可以检测到何时程序不再使用一个对象了,当他确定了一个对象是无用的时候,他就知道不再需要这个对象,可以把它所占用的内存释放掉了

标记清除

​ 当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了,因为环境中的变量已经无法访问到这些变量了,然后垃圾回收器相会这些带有标记的变量机器所占空间。

引用计数

引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。
注意:
当存在循环引用的时候,引用计数会导致问题。要解除变量的引用,即及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用,设为null。

v8垃圾回收

V8采用了一种代回收的策略,将内存分为两个生代:新生代(new generation)老生代(old generation)。新生代中的对象为存活时间较短的对象,老生代中的对象为存活时间较长或常驻内存的对象,分别对新老生代采用不同的垃圾回收算法来提高效率,对象最开始都会先被分配到新生代(如果新生代内存空间不够,直接分配到老生代),新生代中的对象会在满足某些条件后,被移动到老生代,这个过程也叫晋升。

新生代垃圾回收算法

Scavenge算法中的Cheney算法:内存一分为二,一个处于使用状态From,另一个处于闲置状态To,当分配对象时,先是在From空间中进行分配。当开始进行垃圾回收算法时,会检查From空间中的存活对象,这些存活对象将会被复制到To空间中(复制完成后会进行紧缩),而非活跃对象占用的空间将会被释放,用到了两个指针,从根对象用到的对象开始扫描,看他们用到了哪些对象,复制,最后活动对象都在To中,From中则是所有对象,直接释放。完成复制后,From空间和To空间的角色发生对换。

对象的晋升

当一个对象经过多次新生代的清理依旧幸存,这说明它的生存周期较长,也就会被移动到老生代,这称为对象的晋升。具体移动的标准有两种:

  1. 对象从From空间复制到To空间时,会检查它的内存地址来判断这个对象是否已经经历过一个新生代的清理,如果是,则复制到老生代中,否则复制到To空间中。
  2. 对象从From空间复制到To空间时,如果To空间已经被使用了超过25%,那么这个对象直接被复制到老生代。
老生代垃圾回收算法

保存的对象大多数是生存周期很长甚至是常驻内存的对象,老生代占用的内存比较多。垃圾回收策略采用Mark-SweepMark-Compact相结合。V8主要使用Mark-Sweep,在空间不足以对从新生代中晋升过来的对象进行分配时,才使用Mark-Compact。

Mark-Sweep

标记清除分为标记和清除两个阶段。

在标记阶段需要遍历堆中的所有对象,并标记那些活着的对象,然后进入清除阶段。在清除阶段中,只清除没有被标记的对象。由于标记清除只清除死亡对象,而死亡对象在老生代中占用的比例很小,所以效率较高。

标记清除有一个问题就是进行一次标记清楚后,内存空间往往是不连续的,会出现很多的内存碎片。如果后续需要分配一个需要内存空间较多的对象时,如果所有的内存碎片都不够用,将会使得V8无法完成这次分配,提前触发垃圾回收。

Mark-Compact

标记整理正是为了解决标记清除所带来的内存碎片的问题。标记整理在标记清除的基础进行修改,将其的清除阶段变为紧缩极端。在整理的过程中,将活着的对象向内存区的一段移动,移动完成后直接清理掉边界外的内存。紧缩过程涉及对象的移动,所以效率并不是太好,但是能保证不会生成内存碎片。

js中数组 内存分配

问题的提出:
JS 的数组可以存放不同类型的元素、并且数组长度是可变的。数据结构中定义的数组是定长的、数据类型一致的存储结构。这是什么原因?

js中数组分为慢数组和快数组,快数组连续存储,通过索引直接定位;慢数组使用HashTable存储。

数组的 elements 被分为许多类型,其每一个元素占用的内存大小取决于 elements 类型和元素中是否有浮点数。如果有浮点数或者 elements 类型为 PACKED_ELEMETNS,那么每个占8字节,否则4字节

除数字以外的其他类型数据都会以指针的方式存储再数字中,所以除了一些 SMI 不能表示的数字,其他类型和 SMI 能表示的值都可以由32位(4字节)表示。

数组的扩容和收缩机制:如果给数组赋值超出容量的下标会触发扩容机制(不能相差太大,不然会转换位慢数组);如果容量大于等于 length * 2 + 16,会触发收缩机制。

快数组转慢数组
  • 如果快数组扩容后的容量是原来的 9 倍以上,意味着它比 HashTable 形式存储占用更大的内存,快数组会转换为慢数组
  • 如果快数组新增的索引与原来最大索引的差值大于 1024,快数组会被转换会慢数组
慢数组转快数组
  • 当慢数组转换成快数组能节省不少于 50% 的空间时,才会将其转换。
V8执行js的过程

在这里插入图片描述

核心流程编译运行

CPU只能识别机器代码,二进制指令

计算机如何执行高级语言

第一种:解释执行,需要先将输入的源代码通过解析器编译成中间代码 ,之后直接使用解释器解释执行中间代码,然后直接输出结果;

第二种:编译执行,采用这种方式也需要先将源代码转换为中间代码 ,然后我们的编译器再将中间代码编译成机器代码。通常编译成的机器代码是以二进制文件形式存储的,需要执行这段程序的时候直接执行二进制文件就可以了。

编译器:
优点:将源代码编译成可被CPU直接执行的机器指令,因为执行效率更高;
缺点:跨平台支持不好,不同CPU有不同指令集,同一套源代码需要被编译成不同机器语言;
解释器:
优点:更容易跨平台,解释器自身会将源代码转换为当前平台所需的机器语言;
缺点:执行效率低一些,因为每句源码都要经过解释器解释为可执行的机器语言;

执行的具体流程
  1. 执行之前,准备所需的基础环境
    在 V8 启动执行 JavaScript 之前,它还需要准备执行 JavaScript 时所需要的一些基础环境,这些基础环境包括了 堆空间、栈空间、全局执行上下文、全局作用域、消息循环系统、内置函数 等,这些内容都是在执行 JavaScript 过程中需要使用到的。

比如:

  • JavaScript 全局执行上下文就包含了执行过程中的全局信息,比如一些内置函数,全局变量等信息;
  • 全局作用域包含了一些全局变量,在执行过程中的数据都需要存放在 内存 中;
  • 由于 V8 采用了经典的堆和栈的管理内存管理模式,所以 V8 还需要初始化了内存中的堆和栈结构;
  • 另外,要我们的 V8 系统活起来,还需要 初始化消息循环系统 ,消息循环系统包含了 消息驱动器 和 消息队列 ,它如同 V8 的心脏,不断接受消息并决策如何处理消息。
  1. 准备好基础环境,向V8提交要执行的JS代码
    首先,V8 会接收到要执行的 JavaScript 源代码,不过这对 V8 来说只是一堆 字符串,V8 并不能直接理解这段字符串的含义,它需要 结构化 这段字符串;
  2. 结构化字符串(JS源代码)
    结构化,是指信息经过分析后可 分解成多个互相关联的组成部分。各组成部分间有明确的层次结构,方便使用和维护,并有一定的操作规范;
  3. 生成AST、作用域
    结构化之后,就生成了 抽象语法树(AST),AST 是便于 V8 理解的结构;在生成 AST 的同时,V8 还会 生成相关的作用域,作用域中存放相关变量;
  4. 生成字节码
    有了 AST 和 作用域 之后,接下来就可以生成 字节码 了,字节码是介于 AST 和 机器代码 的中间代码。但是与特定类型的机器代码无关,解释器可以直接解释执行字节码 ,或者通过编译器将其编译为二进制的机器代码再执行;
  5. 解释器解释执行字节码
    生成字节码之后,解释器就登场了,它会 按照顺序 解释执行字节码,并输出执行结果;

注意:关于热点代码
在解释执行字节码的过程中,如果发现了某一段代码会被重复多次执行,那么监控器会将这段代码标记为 热点代码。当某段代码被标记为热点代码后,V8 就会将这段字节码丢给 优化编译器,优化编译器会在后台将字节码编译成二进制代码,然后再对编译后的二进制代码执行优化操作,优化后的二进制机器代码的执行效率会得到大幅提升。如果下面再执行到这段代码时,那么 V8 会优先选择优化之后的二进制代码,这样代码的执行速度就会大幅提升。

数据链路层
  • 差错控制:crc、奇偶校验
  • 流量控制:停止等待、滑动窗口(停止等待、后退n、选择重传)协议
  • 可靠传输:确认+超时重传
  • 介质访问控制:CSMA,CSMA/CD(边听边发,冲突停发,随机重发),CSMA/CA(预约信道,二进制退避算法)
  • ppp和hdlc区别
交换机:

多接口网桥,全双工通信,隔离冲突域不隔离广播域,即插即用内部的地址表通过自学习算法自动简历,采取存储转发或者直通式方式进行转发。表的内容:mac地址:接口。过程:A从接口1向B发送一帧,查找交换表,查找到:转发;查找不到:记录信息,并向其他接口广播,目的地址相同的接收,否则丢弃(过滤)。自学习有兜圈子的问题,利用STP生成树协议:不改变实际拓扑,从逻辑上切断一些链路。

ip层:提供主机之间的逻辑通信
  • 路由算法:距离-向量(更新时,对相邻转发自己,慢收敛)RIP(基于UDP)+链路状态(Dijsktra,泛洪法,所有端口转发与自己所有相邻的信息)OSPF
  • CIDR
  • ARP、DHCP、ICMP
  • IPV4IPV6差别
  • BGP寻找一条比较好的路由基于TCP
路由器:路由选择+分组转发

路由表由路由算法得到,转发表由路由表得到

Http
状态码

在这里插入图片描述
常见的状态码:

200:OK请求成功

204:No Content无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档

206Partial Content部分内容。服务器成功处理了部分GET请求

301Moved Permanently永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

302Found临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI

304Not Modified未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源

400Bad Request客户端请求的语法错误,服务器无法理解

401Unauthorized请求要求用户的身份认证

403Forbidden服务器理解请求客户端的请求,但是拒绝执行此请求

404Not Found服务器无法根据客户端的请求找到资源(网页)。

405Method Not Allowed客户端请求中的方法被禁止

408Request Time-out服务器等待客户端发送的请求时间过长,超时

500Internal Server Error服务器内部错误,无法完成请求

501Not Implemented服务器不支持请求的功能,无法完成请求

502Bad Gateway充当网关或代理的服务器,从远端服务器接收到了一个无效的请求

503Service Unavailable由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中

504Gateway Time-out充当网关或代理的服务器,未及时从远端服务器获取请求

505HTTP Version not supported服务器不支持请求的HTTP协议的版本,无法完成处理

  • http基于TCP/IP,无连接、媒体独立(Content-Type)和无状态
  • http状态保持:Cookie和Session就是在客户端和服务器之间保持状态的解决方案
  • 请求报文格式:由3部分组成(请求行+请求头+空行+请求数据)
    • 请求行:请求方法:get/post,url地址,协议名称及版本号
    • 请求头:包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。与缓存相关的规则信息,均包含在header中(cookie在这)
    • 请求体:键值对形式编码成一个格式化串,它承载多个请求参数的数据
  • 响应报文:状态行+消息报头+空行+响应正文
  • https:在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性,HTTPS的安全基础是SSL
    在这里插入图片描述
    由于非对称加密慢,不能每次传输数据都进行非对称加密,所以使用非对称加密将密钥协商好然后使用对称加密进行数据传输
http的content-type格式

上传数据时multipart/form-data
text/(html、plain、xml)、image/(gif、jpg、png)
application/(xml、pdf、json、msword)

http请求的方式

http1.0:GET、POST和HEAD
http1.1:Options、put、delete、trace和connect
在这里插入图片描述
options:返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性

post执行了两次:在发生正式的请求之前,先进行一次预检请求。看服务端返回一些信息,浏览器拿到之后,看后台是否允许进行访问。1:产生了复杂请求 请求中有自定义HTTP头部。所谓的自定义头部,在实际的项目里,我们经常会遇到需要在header头部加上一些token或者其他的用户信息,用来做用户信息的校验。

2:发生了跨域。发出一个options请求,检测服务端是否支持真实的请求进行跨域的请求。真实请求在options请求中,通过request-header将 Access-Control-Request-Headers与Access-Control-Request-Method发送给后台,另外浏览器会自行加上一个Origin请求地址。

只要是带自定义header的跨域请求,在发送真实请求前都会先发送OPTIONS请求,浏览器根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问。所以复杂请求肯定会两次请求服务端。

options请求如何避免:

1:使用代理,避开跨域。

2:将复杂跨域请求更改为简单跨域请求。

3:不使用带自定义配置的header头部。

PUT和POST

PUT和POS都有更改指定URI的语义.但PUT被定义为idempotent的方法,POST则不是.idempotent的方法:如果一个方法重复执行

多次,产生的效果是一样的,那就是idempotent的。也就是说:

PUT请求:如果两个请求相同,后一个请求会把第一个请求覆盖掉。(所以PUT用来改资源)

Post请求:后一个请求不会把第一个请求覆盖掉。(所以Post用来增资源)

get和post

1、GET参数通过URL传递,POST放在Request body中。

2、GET请求会被浏览器主动cache,而POST不会,除非手动设置。

3、GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

4、Get 请求中有非 ASCII 字符,会在请求之前进行转码,POST不用,因为POST在Request body中,通过 MIME,也就可以传输非 ASCII 字符。

5、 一般我们在浏览器输入一个网址访问网站都是GET请求

6、HTTP的底层是TCP/IP。HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本。GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。但是请求的数据量太大对浏览器和服务器都是很大负担。所以业界有了不成文规定,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。

7、GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

8、在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。但并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

http发展史
http0.9:get请求文本
http1.0:
  • 增加了 HEAD、POST 等新方法
  • 增加了响应状态码,标记可能的错误原因
  • 引入了协议版本号概念
  • 引入了 HTTP Header(头部)的概念,让 HTTP 处理请求和响应更加灵活
  • 传输的数据不再局限于文本

头部:键值对,告诉服务端可接受的文件类型、缓存信息、认证信息。

http1.1:解决连接问题
  • 长连接(Connection:keep-alive):引入了 TCP 连接复用,即一个 TCP 默认不关闭,可以被多个请求复用
  • 并发连接:对一个域名的请求允许分配多个长连接(缓解了长连接中的「队头阻塞」问题)
  • 引入管道机制,一个 TCP 连接,可以同时发送多个请求。(响应的顺序必须和请求的顺序一致,因此不常用)
  • 增加了 PUT、DELETE、OPTIONS、PATCH 等新的方法
  • 新增缓存字段(cache-control 、E-tag)
  • 请求头中引入了 range 字段,支持断点续传
  • 允许响应数据分块(chunked),利于传输大文件
  • 强制要求 Host 头,让互联网主机托管称为可能
http2.0

关于http1.1并发能力受限:

  • 一个连接中同一时刻只能处理一个请求。当前的请求没有结束之前,其他的请求只能处于阻塞状态,这种情况被称为「队头阻塞」
  • 浏览器为了减轻服务器的压力,限制了同一个域名下的 HTTP 连接数,即 6 ~ 8 个

http2.0:

  • 针对很多请求报文头部很多内容,实际传输的内容很少,所以做了头部压缩,是开发了专门的HPACK算法,客户端和服务器维护索引表;
  • 二进制帧传输,将每个请求的内容封装成不同的带有编号的二进制帧;然后将这些帧同时发送给服务端。服务端接收到数据之后,会将相同编号的帧合并为完整的请求信息。同样,服务端返回结果、客户端接收结果也遵循这个帧的拆分与组合的过程。
  • 引入虚拟流,多路复用:**多路复用,就是在一个 TCP 连接中可以存在多条流。**换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免 HTTP 旧版本中的队头阻塞问题,极大的提高传输性能。
  • 允许服务器主动向客户推送数据
http3.0:

解决tcp传输层的丢包阻塞问题,使用基于UDP的QUIC协议,自定义重传机制

cdn

通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络”边缘”,使用户可以就近取得所需的内容,解决Internet网络拥塞状况,提高用户访问网站的响应速度。从技术上全面解决由于网络带宽小、用户访问量大、网点分布不均等原因,解决用户访问网站的响应速度慢的根本原因。

缓存控制

浏览器缓存是浏览器在本地磁盘对用户最近请求过的资源进行存储,当访问者再次访问同一资源时,浏览器就可以直接从本地磁盘加载资源,通过缓存的方式就可以减少与服务器的数据传输,减少服务器的负担,加快页面响应速度等。

  • 浏览器在发起对于资源的请求时,会首先检查本地是否存在缓存,如果存在缓存则通过expirescache-control检查缓存是否过期,如果命中缓存且缓存未过期,则直接使用本地缓存。(判断过期没有)
  • 本地缓存未命中,则浏览器向服务器发送一个协商请求,通过last-modifiedetag验证资源是否命中协商缓存,如果命中则服务器会将这个请求响应为304,但是不会返回这个资源的数据,依然是从缓存中读取资源,如果未命中则会携带资源返回且响应为200。(通过If-None-MatchIf-Modified-Since判断是否更改)
强缓存

通过Expires(本地时间)与Cache-Control(相对时间)来控制缓存在本地的有效期。分别是HTTP1.0和HTTP1.1出现。

Cache-Control

  • no-store:缓存中不得存储任何关于客户端请求和服务端响应的内容
  • no-cache:浏览器会将服务端响应的资源进行缓存,但是在每次请求时,缓存都要向服务端评估缓存响应的有效性,协商缓存是否可用,根据响应是304还是200判断是使用本地缓存资源还是使用服务器响应的资源。
  • public || private: public表示该响应可以被任何中间人比如中间代理、CDN等缓存。默认响应为privateprivate表示该响应是专用的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。
  • immutable:在有效期内用户有需求直接读缓存,即使刷新也不向服务器发起请求
  • must-revalidate:表示缓存过期后必须重新向服务器验证
    Expires和cache-cache区别
  1. Expires 是http1.0的产物,Cache-Control是http1.1的产物
  2. 两者同时存在的话,Cache-Control优先级高于Expires;
  3. 在某些不支持HTTP1.1的环境下,Expires就会发挥用处。所以Expires其实是过时的产物,现阶段它的存在只是一种兼容性的写法
  4. Expires是一个具体的服务器时间,这就导致一个问题,如果客户端时间和服务器时间相差较大,缓存命中与否就不是开发者所期望的。Cache-Control是一个时间段,控制就比较容易
协商缓存

表示缓存时间的响应报文首部:Expires(缓存的过期时间)和Last-modified
etag:标识资源,每次资源更新,etag值也会被服务器更新。
服务器的时钟可能会不同步,时间上会产生误差,这样客户端下次进行请求时就可以检查修改资源时间是否一致

Etag 主要为了解决 Last-Modified 无法解决的一些问题。

  1. 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
  2. 某些服务器不能精确的得到文件的最后修改时间
  3. 在方式上,Etag是对资源的一种唯一标识,而Last-Modified是该资源文件最后一次更改时间
  4. 在精确度上,Etag要优于Last-Modified。Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度;如果是负载均衡的服务器,各个服务器生成的Last-Modified也有可能不一致。
  5. 在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。
  6. 在优先级上,服务器校验优先考虑Etag。
url全过程
  1. dns将域名解析成IP地址。在解析过程中,按照浏览器缓存系统缓存路由器缓存ISP(运营商)DNS缓存根域名服务器顶级域名服务器主域名服务器的顺序,逐步读取缓存,直到拿到IP地址。这里使用DNS预解析,可以根据浏览器定义的规则,提前解析之后可能会用到的域名,使解析结果缓存到系统缓存中,缩短DNS解析时间,来提高网站的访问速度
  2. 应用层生成HTTP请求报文,HTTP请求报文(请求行+请求头+请求体)
  3. 传输层建立TCP连接。
  4. 处理来自传输层的数据段segment,将数据段segment装入数据包packet,填充包头,主要就是添加源和目的IP地址,然后发送数据。在数据传输的过程中,IP协议负责选择传送的路线,称为路由功能。(路由表由路由算法生成)
  5. 数据链路层实现网络相邻结点间可靠的数据通信。为了保证数据的可靠传输,把数据包packet封装成帧(Frame),并按顺序传送各帧。由于物理线路的不可靠,发出的数据帧有可能在线路上出错或丢失,于是为每个数据分块计算出CRC(循环冗余检验),并把CRC添加到帧中,这样接收方就可以通过重新计算CRC来判断数据接收的正确性。一旦出错就重传。将数据包packet封装成帧(Frame),包括帧头和帧尾。帧尾是添加被称做CRC的循环冗余校验部分。帧头主要是添加数据链路层的地址,即数据链路层的源地址和目的地址,即网络相邻结点间的源MAC地址和目的MAC地址。
  6. 物理层传输数据数。据链路层的帧(Frame)转换成二进制形式的比特(Bit)流,从网卡发送出去,再把比特转换成电子、光学或微波信号在网络中传输

网络传输:从客户机到服务器需要经过很多网络设备:比特流到达集线器后,集线器简单地对比特流进行放大,从除接收端口以外的所有端口转发出去, 交换机是数据链路层设备,比特流到达交换机,交换机除了对比特流进行放大外,还根据源MAC地址进行学习,根据目的MAC地址进行转发。交换机根据数据帧中的目的MAC地址査询MAC地址表,把比特流从对应的端口发送出去, 路由器是网络层设备,路由器收到比特流,转换成帧上传到数据链路层,路由器比较数据帧的目的MAC地址,如果有与路由器接收端口相同的MAC地址,则路由器的数据链路层把数据帧进行解封装,然后上传到路由器的网络层,路由器找到数据包的目的IP地址,并查询路由表,将数据从入端口转发到出端口。接着在网络层重新封装成数据包packet,下沉到数据链路层重新封装成帧frame,下沉到物理层,转换成二进制比特流,发送出去。

服务器处理及反向传输:服务器接收到这个比特流,把比特流转换成帧格式,上传到数据链路层,服务器发现数据帧中的目的MAC地址与本网卡的MAC地址相同,服务器拆除数据链路层的封装后,把数据包上传到网络层。服务器的网络层比较数据包中的目的IP地址,发现与本机的IP地址相同,服务器拆除网络层的封装后,把数据分段上传到传输层。传输层对数据分段进行确认、排序、重组,确保数据传输的可靠性。数据最后被传到服务器的应用层。HTTP服务器,生成响应报文,报文主体内容是首页的HTML页面。接着,通过传输层、网络层、数据链路层的层层封装,最终将响应报文封装成二进制比特流,并转换成其他信号,如电信号到网络中传输,反向传输的过程与正向传输的过程类似

浏览器渲染:客户机接受到二进制比特流之后,把比特流转换成帧格式,上传到数据链路层,客户机发现数据帧中的目的MAC地址与本网卡的MAC地址相同,拆除数据链路层的封装后,把数据包上传到网络层。网络层比较数据包中的目的IP地址,发现与本机的IP地址相同,拆除网络层的封装后,把数据分段上传到传输层。传输层对数据分段进行确认、排序、重组,确保数据传输的可靠性。数据最后被传到应用层。

  • 浏览器处理HTTP响应报文中的主体内容,首先使用loader模块加载相应的资源,主资源加载路径(html)和派生资源加载路径(html中用到的资源)。
  • 主资源到达后,浏览器的Parser模块解析主资源的内容,生成派生资源对应的DOM结构,然后根据需求触发派生资源的加载流程。使用parse模块解析HTML、CSS、Javascript资源
运输层:提供进程之间的逻辑通信

面向通信的最高层,用户功能的最低层。

  • 差错控制:序号、确认和重传
  • 端口:传输层和应用层的通道(标识应用进程)
  • 流量控制:根据接收缓存大小调整窗口大小,限制速率,接收窗口
  • 拥塞控制:大小跟带宽和时延相关,拥塞窗口。
tcp保证可靠传输
  1. 检验和:发送方把数据报分成16位数据,反码相加,结果放检验和中,接收方同,最后结果是所有位置1是对的。
  2. 确认应答与序列号
    1. 序列号的作用:保证可靠性(缺少某个序号能知道
    2. 保证按序到达
    3. 累计确认,丢失的包裹就从该处开始重传
    4. 去重
  3. 超时重传:在一定的时间间隔后还没收到ack,重传
  4. 连接机制,三次握手,四次挥手
  5. 流量控制:接收端根据自己的缓存区大小以及发送方发送的数据量,反馈窗口大小
  6. 拥塞控制:慢启动(探清当前的网络拥塞状况),指数增长有门限值按线性增(拥塞避免)长直到网络拥塞,乘法减小,门限值half,新的窗口大小=门限值
tcp丢包

产生原因:

  1. TCP是基于不可靠的网路实现可靠传输,肯定会存在丢包问题。
  2. 如果在通信过程中,发现缺少数据或者包,那边么最大的可能性是程序发送过程或者接受过程中出现问题。

解决:

  • 数据分片:发送端对数据进行分片,接受端要对数据进行重组,由TCP确定分片的大小并控制分片和重组
  • 到达确认:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认
  • 超时重发:发送方在发送分片时设置超时定时器,如果在定时器超时之后没有收到相应的确认,重发分片数据
  • 滑动窗口:TCP连接的每一方的接受缓冲空间大小固定,接收端只允许另一端发送接收端缓冲区所能接纳的数据,TCP在滑动窗口的基础上提供流量控制,防止较快主机致使较慢主机的缓冲区溢出
  • 失序处理:作为IP数据报来传输的TCP分片到达时可能会失序,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层;
  • 重复处理:作为IP数据报来传输的TCP分片会发生重复,TCP的接收端必须丢弃重复的数据;
  • 数据校验:TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到分片的检验或有差错,TCP将丢弃这个分片,并不确认收到此报文段导致对端超时并重发

tcp(全双工通信)三次握手四次挥手

  • 确认位ACK:在连接后所有传送的报文段都必须把ACk置1
  • 同步位SYN:SYN=1表示这是一个连接请求或者连接接收报文
  • 有两个结束等待的阶段,1.等待服务端收到请求报文,2.等待服务端把数据传完

tcp和udp区别
在这里插入图片描述

应用层
socket:ip+协议+端口号(标识网络中的进程)

在这里插入图片描述

dns

域名–>ip地址、udp报文、本地–>其他、递归解析查询和迭代解析查询、根->顶级(com、cn)->权限(edu.cn)->本地

跨域
  • jsonp:jsonp选script的src进行跨域,因为带有src属性和部分的href属性是可以跨域的,而其中只有js能够对数据进行控制、显示等。(请求一段 JS 脚本,把执行这段脚本的结果当做数据,所以不能post)
  • CORS:基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否。指定授权访问的域,授权请求的方法等。Access-Control-Allow-Origin
  • 使用websocket协议,利用webSocket的API,可以直接new一个socket实例,然后通过open方法内send要传输到后台的值,也可以利用message方法接收后台传来的数据。
  • 服务器端代理请求:正向代理隐藏真实客户端,反向代理隐藏真实服务端。客户端直接发送请求给代理服务器,然后代理服务器会根据客户端的请求,从真实的资源服务器中获取资源返回给客户端。所以反向代理就隐藏了真实的服务器。利用这种特性,我们可以通过将其他域名的资源映射成自己的域名来规避开跨域问题。
  • proxy跨域:可实现多个
浏览器重绘、回流、重排

chrome叫重排,firefox叫回流
一旦渲染树(dom树和style树构成)构建完成,就要开始绘制(paint)页面元素了
当DOM的变化引发了元素几何属性的变化,比如改变元素的尺寸元素的位置隐藏等,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。完成重排后,浏览器会重新绘制受影响的部分到屏幕中,这个过程就是“重绘”。

重排负责元素的几何属性更新,重绘负责元素的样式更新。而且,重排必然带来重绘,但是重绘未必带来重排。比如,改变某个元素的背景,这个就不涉及元素的几何属性,所以只发生重绘。重排需要重新计算,开销比重绘大,要尽量避免

重排的产生:

  1. 页面第一次渲染,所有组件进行首次布局
  2. 浏览器窗口尺寸改变、元素尺寸、位置改变
  3. 新增、删除可见元素
  4. 内容发生变化
  5. 元素字体大小变化等

重绘的产生:
当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如visibility、outline、背景色等属性的改变。

避免方法:

  1. 样式集中改变
  2. 缓存布局信息
  3. position属性设置为absolute或fixed
  4. 避免频繁操作DOM,创建一个documentFragment(轻量级的document对象,它设计的目的就是用于更新等操作),在它上面应用所有DOM操作,最后再把它添加到文档中。
  5. display:none修改后再block
安全
csrf跨站请求伪造

用户访问受信任的网站A,A产生Cookie返回给用户;用户访问B网站,B网站返回攻击代码并发出请求访问A,带着cookie访问,网站A根据cookie给其返回数据
防御CSRF攻击

  • 验证HTTP Referer字段。HTTP头中的一个字段,记录了该请求的来源地址。
  • 在请求地址中添加token并验证。
  • 服务端在收到路由请求时,生成一个随机数,在渲染请求页面时把随机数埋入页面(一般埋入 form 表单内,服务端设置setCookie,把该随机数作为cookie或者session种入用户浏览器,当用户发送 GET 或者 POST 请求时带上_csrf_token参数,后台接收并比对。

注意:少用get请求

xss跨站脚本攻击

跨站脚本攻击XSS,是最普遍的Web应用安全漏洞。这类漏洞能够使得攻击者嵌入恶意脚本代码到正常用户会访问到的页面中,当正常用户访问该页面时,则可导致嵌入的恶意脚本代码的执行,从而达到恶意攻击用户的目的。
类型:

  • 反射型XSS: 攻击者事先制作好攻击链接,需要欺骗用户自己去点击链接才能触发XSS代码,所谓反射型XSS就是将恶意用户输入的js脚本,反射到浏览器执行。
  • 存储型XSS:代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,每当有用户访问该页面的时候都会触发代码执行,这种XSS非常危险,容易造成蠕虫,大量盗窃cookie,也被称为持久型XSS
  • DOMXSS:类似于反射型XSS,但这种XSS攻击的实现是通过对DOM树的修改而实现的。

攻击者可以使用户在浏览器中执行其预定义的恶意脚本,劫持用户会话,插入恶意内容、重定向链接、使用恶意软件劫持用户浏览器等等。

防御XSS攻击
  • 在用户提交参数前,将提交的字符<>&"'+/等进行转义,严格控制输出。
  • 将输入转化为小写对比javascript:,若匹配则过滤。
  • cookie设置为http-only,js脚本将无法读取到cookie信息。
  • 纯前端渲染,明确innerTextsetAttributestyle,将代码与数据分隔开。
  • 避免不可信的数据拼接到字符串中传递给这些API,如DOM中的内联事件监听器,locationonclickonerroronloadonmouseover等,<a>标签的href属性,JavaScripteval()setTimeout()setInterval()等,都能把字符串作为代码运行。
  • 对于不受信任的输入,都应该限定一个合理的长度。
  • 严格的CSP,禁止加载外域代码,禁止外域提交,禁止内联脚本执行等较为严格的方式。
sql注入

SQL注入攻击是通过操作输入来修改SQL语句,用以达到执行代码对WEB服务器进行攻击的方法。简单的说就是在post/get表单、输入域名或页面请求的查询字符串中插入SQL命令,最终使web服务器执行恶意命令的过程。

通过sql语句实行网络攻击甚至篡改数据库

程序要接收客户端传的变量或者url传递参数,解析url作为sql语句的一部分

注入过程
  1. 注入点探测。适当的分析应用程序,可以判断什么地方存在SQL注入点
  2. 观察系统行为。观察后端是否将数据库错误信息向前端返回、http中的响应信息等。
  3. 数据获取。判断字段长度、回显位置、数据库信息,查找数据库表名、字段名等构建SQL进行注入,登录后台,数据盗取,进行服务器提权等操作。
防御SQL注入
  1. 严格检查变量数据类型和格式(比如邮箱等)
  2. 过滤特殊符号、拦截非正常请求。对于无法确定固定格式的变量,一定要进行特殊符号过滤或转义处理。
  3. 绑定变量,使用预编译语句
    1. 预编译的优势:一次编译、多次运行
    2. 用占位符代替值,先编译,执行的时候再把值代入,这样做到了值和语句分离,是并的关系。
    3. mybatis的#符号中带的变量都会自动加上引号
CSS劫持攻击(点击劫持)

大概有两种方式,一是攻击者使用一个透明的iframe,覆盖在一个网页上,然后诱使用户在该页面上进行操作,此时用户将在不知情的情况下点击透明的iframe页面;二是攻击者使用一张图片覆盖在网页,遮挡网页原有位置的含义;

iframe防御

X-FRAME-OPTIONS是目前最可靠的方法。
X-FRAME-OPTIONS是微软提出的一个HTTP头,专门用来防御利用iframe嵌套的点击劫持攻击。

DENY // 拒绝任何域加载
SAMEORIGIN // 允许同源域下加载
ALLOW-FROM // 可以定义允许frame加载的页面地址

图片覆盖攻击

攻击者使用一张或多张图片,利用图片的style或者能够控制的CSS,将图片覆盖在网页上,形成点击劫持。当然图片本身所带的信息可能就带有欺骗的含义,这样不需要用户点击,也能达到欺骗的目的。

解决

在防御图片覆盖攻击时,需要检查用户提交的HTML代码中,img标签的style属性是否可能导致浮出。

http首部注入攻击

通过在响应首部字段插入换行,添加任意响应首部或主体的一种攻击

影响

  • 设置任何Cookie信息
  • 重定向至任意URL
  • 显示任意的主体(HTTP响应截断攻击)

防范: 使用https,对http报文做加密、认证及完整性保护,防止篡改。

dns劫持

打开百度或者输入你正确的目标域名网址,整个网页却被强制跳转到XX娱乐城,这就是典型的DNS劫持。

解决:
  1. 互联网公司准备两个以上的域名,一旦黑客进行DNS攻击,用户还可以访问另一个域名。
Ddos攻击

攻击者使用一个非法账号将DDoS主控程序安装在一台计算机上,并在网络上的多台计算机上安装代理程序。在所设定的时间内,主控程序与大量代理程序进行通讯,代理程序收到指令时对目标发动攻击,主控程序甚至能在几秒钟内激活成百上千次代理程序的运行。

DDoS攻击的危害

DDoS攻击会对您的业务造成以下危害:

  • 重大经济损失

    在遭受DDoS攻击后,您的源站服务器可能无法提供服务,导致用户无法访问您的业务,从而造成巨大的经济损失和品牌损失。

    例如:某电商平台在遭受DDoS攻击时,网站无法正常访问甚至出现短暂的关闭,导致合法用户无法下单购买商品等。

  • 数据泄露

    黑客在对您的服务器进行DDoS攻击时,可能会趁机窃取您业务的核心数据。

  • 恶意竞争

    部分行业存在恶性竞争,竞争对手可能会通过DDoS攻击恶意攻击您的服务,从而在行业竞争中获取优势。

    例如:某游戏业务遭受了DDoS攻击,游戏玩家数量锐减,导致该游戏业务几天内迅速彻底下线。

解决:

优化dns解析、提供余量带宽

Cookie、Session、Token
Cookie由服务器产生,保存在客户端(本地缓存)

cookie保存在客户端的硬盘上,下次再访问该网站的时候,浏览器先检查有没有 cookie,如果有的话,就读取该 cookie,然后发送给服务器。他不安全,不是很重要的信息可放在cookie中(类比看电影时边看边下载),数据载体!跟随着http请求发送。

  1. 用于解决http无状态的缺点,在客户端存储会话信息,记录用户的状态
  2. 也就是我们现在也经常使用cookie在客户端存储一些数据
Set-Cookie:key=value;expires=date;domain=domain;path=path;secure

Key/value表示在服务端可跟踪、可识别的用户信息;
expires表示Cookie的结束日期,如果没指定,Cookie会在用户退出浏览器时过期;
domain告诉浏览器这个Cookie可以被发送到哪个域名,如果没指定,默认为产生Cookie的服务器主机名,浏览器会存储很多不同网站的Cookie,浏览器会根据domain的值将Cookie发送到对应的域名下;
path指定Cookie对哪些请求路径生效,如果没指定,默认为产生Cookie的URL路径;
secure表示在使用SSL安全连接时才发送Cookie,若没设置secure,则没限制。

设置HttpOnly属性,通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击,窃取cookie内容,这样就增加了cookie的安全性

sameSite属性

Strict、Lax和None
Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

Session由服务器产生,保存在服务器

会话,代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续,会话的时间和id被记录。cookie中存放着一个sessionID,请求时会发送这个ID;Session被临时保存在服务器上,指访问者从到达某个特定主页到离开为止的那段时间。客户端每次请求服务器的时候会发送当前会话的sessionid,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登录或具有某种权限。(一般用于登录等)

Token

token表示令牌,是用户身份的验证方式。在网络中比如会话令牌(session toke),作为会话的唯一标识符(不存储会话信息,无状态)。

JWT:

header头文件信息、 payload 荷载、signature加密验证

  • 根据前两者编码然后利用算法进行加密生成签名
  • 客户端使用用户名跟密码请求登录
  • 服务端收到请求,去验证用户名与密码
  • 验证成功后,服务端会根据用户id、用户名、定义好的秘钥、过期时间生成一个 Token,再把这个 Token 发送给客户端
  • 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  • 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
    服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

MVC

MVVM

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值