组件通信

Vue3 组件通信方式 props $emit expose / ref $attrs v-model provide / inject Vuex mitt Vue3 通信使用写法 1. props 用 props 传数据给子组件有两种方法,如下 方法一,setup() 方法写法 // Parent.vue 传送 <child :msg1="msg1" :msg2="msg2"></child> <script> import child from "./child.vue" import { ref, reactive } from "vue" export default { data(){ return { msg1:"这是传级子组件的信息1" } }, setup(){ // 创建一个响应式数据 // 写法一 适用于基础类型 ref 还有其他用处,下面章节有介绍 const msg2 = ref("这是传级子组件的信息2") // 写法二 适用于复杂类型,如数组、对象 const msg2 = reactive(["这是传级子组件的信息2"]) return { msg2 } } } </script> // Child.vue 接收 <script> export default { props: ["msg1", "msg2"],// 如果这行不写,下面就接收不到 setup(props) { console.log(props) // { msg1:"这是传给子组件的信息1", msg2:"这是传给子组件的信息2" } }, } </script> 方法二,setup 语法糖 ...

October 4, 2024

Promise

Promise 是在 ES6 出现的新功能,并且是用来优化过去回调函式 callback 的写法。这篇面试详解中会讨论到, promise 是什么、为什么需要有 Promise,以及延伸到 async/await 相关问题。 为什么要使用 Promise? 在探讨 Promise 之前,我们先来看一下为什么需要它的出现。 JavaScript 中有一个重要概念 - 异步 (async),它允许我们在执行耗时任务时,不必等待程式完成,而是继续执行下面的代码,直到任务完成再通知。常用的异步操作有:文件操作、数据库操作、AJAX 以及定时器等。 JavaScript 有两种实现异步的方式: 第一种:回调函式 callback function 在 ES6 promise 出现之前,通常使用回调函式 (callback) 实现异步操作。但使用回调函式 callback 存在一个明显的缺点,当需要执行多个异步操作时,代码会不断往内嵌套,这种情况通常被称为「callback 地狱」(callback hell)。 callback(() => { console.log("Hello!"); callback(() => { console.log("Hello!"); callback(() => { console.log("Hello!"); callback(() => { console.log("Hello!"); }, 200); }, 200); }, 200); }, 200); 而为了解决这种问题,就出现了第二种方法 - promise。 什么是 Promise? 上一段提到 Promise 出现的原因,这一段我们来看那到底 Promise 是什么。 ...

October 2, 2024

点击劫持

一、简介 点击劫持是一种视觉上的欺骗手段。攻击者使用一个透明的、不可见的iframe,覆盖在一个网页上,然后诱使用户在该网页上进行操作,此时用户在不知情的情况下点击透明的iframe页面。通过调整iframe页面的位置,可以诱使用户恰好点击在iframe页面的一些功能性按钮上。 虽然受害者点击的是他所看到的网页,但其实他所点击的是被黑客精心构建的另一个置于原网页上面的透明页面 Clickjacking 是仅此于 XSS 和 CSRF 的前端漏洞,因为需要诱使用户交互,攻击成本高,所以不被重视,但危害不容小觑。 点击劫持的步骤 黑客创建一个网页利用 iframe 包含目标网站; 隐藏目标网站,使用户无法无法察觉到目标网站存在; 构造网页,诱变用户点击特点按钮; 用户在不知情的情况下点击按钮,触发执行恶意网页的命令; 二、劫持类型 2.1 Flash点击劫持 攻击者通过flash构造了点击劫持,在完成一系列复杂的动作后,最终控制了用户的摄像头。 攻击者制作了一个Flash游戏,这个游戏就是让用户去点击“CLICK”按钮,每次点击后这个按钮的位置都会发生变化。在Flash上面隐藏了一个看不见的iframe,游戏中某些点击时是有意义的,有些点击是无效的。 攻击通过诱导用户鼠标点击就能完成较复杂的动作。最终通过这一步步操作,打开了用户的摄像头。 2.2 图片覆盖攻击 点击劫持是一种视觉上的欺骗手段。那么图片覆盖也可以起到类似的作用。简称XSIO(Cross Site Image Overlaying) 原理: 利用的是图片的style,或者能够控制CSS。如果应用没有限制style的position为absolute的话,图片可以覆盖到页面上的任意位置。 <img style="position: absolute; left: 100px; top: 100px"> 用户点击图片,就会链接到其他网站。 图片还可以伪装得像一个正常的链接、按钮;或者在图片中构造一些文字,覆盖在关键的位置,就有可能完全改变页面中想表达的意思。这种情况下,不需要用户点击,也能达到欺骗的目的。 由于img标签在很多系统中是对用户开放的,因此在现实生活中有非常多的站点存在在XSIO攻击的可能。在防御XSIO时,需要检查用户提交的HTML代码中,img标签的style属性是否可能导致浮出。 2.3 拖拽劫持与数据窃取 目前,许多浏览器都开始支持Drag和Drop的API。对于用户来说,拖拽使他们的操作更加简单。浏览器中的拖拽对象可以是一个链接,也可以是一段文字,还可以从一个窗口拖拽到另一个窗口,因此拖拽是_不受同源策略限制_的。 拖拽劫持的思路是诱使用户从隐藏不可见iframe中拖拽出攻击者希望得到的数据,然后放到攻击者能控制的另外一个页面,从而窃取数据。在JavaScript的支持下,这个攻击过程会变得非常隐蔽,因为它突破了传统ClickJacking一些先天的局限,所以这种新型的拖拽劫持能够造成更大的破坏。 2.4 ClickJacking3.0:触屏劫持 智能手机的 触屏劫持 攻击被斯坦福的安全研究者公布,这意味着ClickJacking的攻击方式更进一步,斯坦福安全研究者的将其称为TapJacking。 从手机角度来看,触屏实际上就是一个事件,手机捕捉这些事件,并执行相应的动作。 常见的几个事件: touchstart: 手指触摸屏幕时发生 touchend: 手指离开屏幕时发生 touchmove: 手指滑动时发生 touchcancel: 系统可取消touch事件 将一个不可见的iframe覆盖到当前网页上,就可以劫持用户的触屏操作。 在未来,随着移动设备中浏览器功能的丰富,我们会看到更多的TapJacking 三、防御 3.1 防御ClickJacking 3.1.1 frame busting 通过可以写一段JavaScript代码,以禁止iframe的嵌套。这种方法叫作frame busting。比如 ...

October 2, 2024

响应式图片

响应式是指实现不同屏幕分辨率的终端上浏览网页的不同展示方式。 本知识点的主要内容有: 为什么要使用响应式图片 怎么实现响应式图片 1、为什么要使用响应式图片 假如有一张图片的显示宽度为200px,那么,它在 1x(即设备像素比为 1 的显示器) 的显示器上,是占了 200 个物理像素(即实际所占的像素);它在 2x 的显示器上,实际上是占了 400 个物理像素;在 3x 的显示器上,实际上是占了 600 个物理像素;在 4x 的显示器上就是占了 800 个物理像素。 如果这个图片只提供 200 像素的尺寸,那么在 2x~4x 的显示器上看起来就很模糊。如果只提供 800 像素的版本,那么在 1x~3x 的设备上会显得多余,因为加载时间会相较长,所以我们要使用响应式图片。 再比如一个场景,相同的banner,在电脑上需要使用大图,但是手机上面使用小图,不然会造成手机上加载慢浪费流量等问题,这也可以使用响应式图片来解决。 2、实现方法 css3 media query 一个办法是使用backgound-image结合媒体查询,如下所示: .banner{ background-image: url(/static/large.jpg); } @media screen and (max-width: 767px){ background-image: url(/static/small.jpg); } 这种方法的缺点是对SEO不太友好,因为如果使用img标签还可以写个alt属性。 picture标签 <picture> <source srcset="banner_w1000.jpg" media="(min-width: 801px)"> <source srcset="banner_w800.jpg" media="(max-width: 800px)"> <img src="banner_w800.jpg" alt=""> </picture> 如上,如果页面宽度大于800px(PC),则加载大图,而在手机上加载小图。这样写浏览器就只会加载source里面的一张图片。但是如果是用js动态插进去的,它还是会去加载两张,只有写在html里面加载初始化页面的时候才只加载一张。 picture必须要写img标签,否则无法显示,对picture的操作最后都是在img上面,例如onload事件是在img标签触发的,picture和source是不会进行layout的,它们的宽和高都是0。 另外使用source,还可以对图片格式做一些兼容处理: <picture> <source type="image/webp" srcset="banner.webp"> <img src="banner.jpg" alt=""> </picture> webp在保持同等清晰度的情况下,体积可以减少一半,但是目前只有Chrome支持,Safari和firefox一直处于实验阶段,所以其它的浏览器如firefox将会加载jpg格式的照片: ...

September 27, 2024

持续集成/持续部署(CI/CD)

传统应用发布模式 开发人员:在开发环境完成代码编写,单元测试,测试通过后提交到代码仓库 运维人员:把项目部署到测试环境,供QA团队测试,测试通过后,部署生成环境 测试人员:进行测试,测试完成后通知运维部署生产环境 缺点 项目在早期就存在错误,但到最后集成的时候才发现 需要手动操作,易错率高 开发与运维需要及时沟通 有了以上缺点,那么就有了CI/CD CI/CD 持续集成(CI): 合并开发人员正在编写的所有代码 一天内进行多次合并和提交代码 从存储库或生产环境中进行构建和自动化测试,确保没有集成问题并及早发现任何问题 持续交付(CD): 可以通过将更改自动推送到发布系统来随时将软件发布到生产环境中 持续部署,并自动将更改推送到生产中 GitLab内置CI/CD 运行流水线任务 Job 在文件中可以定义一个或多个作业,每个作业具有唯一的名称,每个作业是独立执行的,每个作业至少包含一个script stages: 用于定义作业可以使用的阶段,并且是全局定义,同一个阶段的作业并行运行,不同阶段按顺序运行 only: 用分支策略来限制jobs构建 script: 项目中package中的脚本 environment: 定义此作业完成部署的环境名称 下面是每个jobs的详细变量名 Keyword Required Description script yes Runner执行的命令或脚本 image no 所使用的docker镜像,查阅使用docker镜像 services no 所使用的docker服务,查阅使用docker镜像 stage no 定义job stage(默认:test) type no stage的别名(已弃用) variables no 定义job级别的变量 only no 定义一列git分支,并为其创建job except no 定义一列git分支,不创建job tags no 定义一列tags,用来指定选择哪个Runner(同时Runner也要设置tags) allow_failure no 允许job失败。失败的job不影响commit状态 when no 定义何时开始job。可以是on_success,on_failure,always或者manual dependencies no 定义job依赖关系,这样他们就可以互相传递artifacts cache no 定义应在后续运行之间缓存的文件列表 before_script no 重写一组在作业前执行的命令 after_script no 重写一组在作业后执行的命令 environment no 定义此作业完成部署的环境名称 coverage no 定义给定作业的代码覆盖率设置 配置.gitlab-ci.yml stages: - deploy_dev - deploy_test - deploy_production deploy_dev: stage: deploy_dev environment: name: dev only: - dev script: - rsync -av . ${WORKSPACE_PATH} && cd ${WORKSPACE_PATH} - npm run build:dev - ansible-playbook ansible-deploy.yml --extra-vars "hosts=cloud_ui_test projectDir=${WORKSPACE_DIST_PATH} projectName=${PROJECT_NAME} webRootPath=/opt/devroot/" deploy_test: stage: deploy_test environment: name: test only: - master script: - rsync -av . ${WORKSPACE_PATH} && cd ${WORKSPACE_PATH} - npm run build:stage - ansible-playbook ansible-deploy.yml --extra-vars "hosts=cloud_ui_test projectDir=${WORKSPACE_DIST_PATH} projectName=${PROJECT_NAME} webRootPath=${WEB_ROOT_PATH}" deploy_production: stage: deploy_production only: - production when: manual script: - npm install - npm run build:prod - ansible-playbook ansible-deploy.yml --extra-vars "hosts=dvs-front-prod projectDir=${PROJECT_PATH} projectName=xianglin-cloud-ui/${PROJECT_NAME} webRootPath=/opt/" 上面这个.yml文件,我们首先定义了三个阶段,deploy_dev部署到dev环境,并且拉去的是dev分支代码; deploy_test部署到test环境,拉去的是master分支代码,deploy_production拉取production分支代码,执行完后需要手动操作 ...

August 7, 2025

正向代理和反向代理

1. 概念 正向代理是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从原始服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转交并且将获得的内容返回给客户端。正向代理的情况下客户端必须要进行一些特别的设置才能使用。 反向代理正好相反。对于客户端来说,反向代理就好像目标服务器。并且客户端不需要进行任何设置。客户端向反向代理发送请求,接着反向代理判断请求走向何处,并将请求转交给客户端,使得这些内容就好似他自己一样,一次客户端并不会感知到反向代理后面的服务,也因此不需要客户端做任何设置,只需要把反向代理服务器当成真正的服务器就好了。 2. 区别 正向代理需要你主动设置代理服务器ip或者域名进行访问,由设置的服务器ip或者域名去获取访问内容并返回;而反向代理不需要你做任何设置,直接访问服务器真实ip或者域名,但是服务器内部会自动根据访问内容进行跳转及内容返回,你不知道它最终访问的是哪些机器。 正向代理是代理客户端,为客户端收发请求,使真实客户端对服务器不可见;而反向代理是代理服务器端,为服务器收发请求,使真实服务器对客户端不可见。 从上面的描述也能看得出来正向代理和反向代理最关键的两点区别: 是否指定目标服务器 客户端是否要做设置 下面用一张图来表示两者的差异: 正向代理与反向代理 正向代理中,proxy和client同属一个LAN,对server透明; 反向代理中,proxy和server同属一个LAN,对client透明。 实际上proxy在两种代理中做的事都是代为收发请求和响应,不过从结构上来看正好左右互换了下,所以把前者那种代理方式叫做正向代理,后者叫做反向代理。 从用途上来区分: 正向代理:正向代理用途是为了在防火墙内的局域网提供访问internet的途径。另外还可以使用缓冲特性减少网络使用率 反向代理:反向代理的用途是将防火墙后面的服务器提供给internet用户访问。同时还可以完成诸如负载均衡等功能 从安全性来讲: 正向代理:正向代理允许客户端通过它访问任意网站并且隐蔽客户端自身,因此你必须采取安全措施来确保仅为经过授权的客户端提供服务 反向代理:对外是透明的,访问者并不知道自己访问的是代理。对访问者而言,他以为访问的就是原始服务器 3. 使用场景 正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用率。反向代理的典型用途是将 防火墙后面的服务器提供给Internet用户访问。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。 3.1 正向代理 从上面的介绍也就可以猜出来正向代理的至少一个功能(俗称翻墙),也即: 用户A无法访问facebook,但是能访问服务器B,而服务器B可以访问facebook。于是用户A访问服务器B,通过服务器B去访问facebook,,服务器B收到请求后,去访问facebook,facebook把响应信息返回给服务器B,服务器B再把响应信息返回给A。这样,通过代理服务器B,就实现了翻墙。 3.2 反向代理 从上面的介绍也可以猜出来反向代理的至少一个功能(比如负载均衡),也即: 假设用户A访问 **www.somesite.com/something.html**,但 www.somesite.com 上并不存在something.html页面,于是接收用户请求的该服务器就偷偷从另外一台服务器上取回来,然后返回给用户,而用户并不知道something.html页面究竟位于哪台机器上。 反向代理的作用就比较多了,这里简单列举一下: 保护和隐藏原始资源服务器 加密和SSL加速 负载均衡 缓存静态内容 压缩 减速上传 安全 外网发布 下面做两个简单介绍 保护和隐藏原始资源服务器 代理作用 用户A始终认为它访问的是原始服务器B而不是代理服务器Z,但实用际上反向代理服务器接受用户A的应答,从原始资源服务器B中取得用户A的需求资源,然后发送给用户A。由于防火墙的作用,只允许代理服务器Z访问原始资源服务器B。尽管在这个虚拟的环境下,防火墙和反向代理的共同作用保护了原始资源服务器B,但用户A并不知情。 负载均衡 负载均衡 当反向代理服务器不止一个的时候,我们甚至可以把它们做成集群,当更多的用户访问资源服务器B的时候,让不同的代理服务器Z(x)去应答不同的用户,然后发送不同用户需要的资源。 3.3 透明代理 透明代理比较类似正向代理的功能,差别在于客户端根本不知道代理的存在,它改编你的request,并会传送真实IP(使用场景就是公司限制网络的访问)。 比如为了工作效率或者安全,A公司屏蔽了QQ软件的使用。A公司的员工接上了网络,但发现无法使用qq。这就是透明代理捣的鬼。公司在内网和外网的中间插入一个透明代理,这个代理会根据规则抓取请求内容,遇到qq的请求我就把这个请求给屏蔽掉,这样就完成了透明屏蔽。当然了,如果你明白原理,就可以自己搞个正向代理来绕过公司的屏蔽。 Nginx作为时下最流行的HTTP服务器之一,同时它是一个反向代理服务器,提到反向代理服务器,有同学可能觉得这个概念很模糊,如果说到代理,他可能明白,但是再引出一个正向代理,估计懵了,笔者将尝试用浅显易懂的比方把这两个概念解释清楚。 正向代理 A同学在大众创业、万众创新的大时代背景下开启他的创业之路,目前他遇到的最大的一个问题就是启动资金,于是他决定去找马云爸爸借钱,可想而知,最后碰一鼻子灰回来了,情急之下,他想到一个办法,找关系开后门,经过一番消息打探,原来A同学的大学老师王老师是马云的同学,于是A同学找到王老师,托王老师帮忙去马云那借500万过来,当然最后事成了。不过马云并不知道这钱是A同学借的,马云是借给王老师的,最后由王老师转交给A同学。这里的王老师在这个过程中扮演了一个非常关键的角色,就是代理,也可以说是正向代理,王老师代替A同学办这件事,这个过程中,真正借钱的人是谁,马云是不知道的,这点非常关键。 我们常说的代理也就是只正向代理,正向代理的过程,它隐藏了真实的请求客户端,服务端不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替来请求,知名的科学上网工具shadowsocks 扮演的就是典型的正向代理角色。在天朝用浏览器访问 www.google.com 时,被残忍的拒绝了,于是你可以在国外搭建一台代理服务器,让代理帮我去请求google.com,代理把请求返回的相应结构再返回给我。 _ 反向代理 大家都有过这样的经历,拨打10086客服电话,可能一个地区的10086客服有几个或者几十个,你永远都不需要关心在电话那头的是哪一个,叫什么,男的,还是女的,漂亮的还是帅气的,你都不关心,你关心的是你的问题能不能得到专业的解答,你只需要拨通了10086的总机号码,电话那头总会有人会回答你,只是有时慢有时快而已。那么这里的10086总机号码就是我们说的反向代理。客户不知道真正提供服务人的是谁。 反向代理隐藏了真实的服务端,当我们请求 www.baidu.com 的时候,就像拨打10086一样,背后可能有成千上万台服务器为我们服务,但具体是哪一台,你不知道,也不需要知道,你只需要知道反向代理服务器是谁就好了,www.baidu.com 就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到真实的服务器那里去。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。 ...

July 28, 2025

react 事件机制

一 前言 我们来一起探讨一下React事件原理,这篇文章,我尽量用通俗简洁的方式,把React事件系统讲的明明白白。 我们讲的react版本是16.13.1 , v17之后react对于事件系统会有相关的改版,文章后半部分会提及。 老规矩,在正式讲解react之前,我们先想想这几个问题(如果我是面试官,你会怎么回答?): 我们写的事件是绑定在dom上么,如果不是绑定在哪里? 为什么我们的事件不能绑定给组件? 为什么我们的事件手动绑定this(不是箭头函数的情况) 为什么不能用 return false 来阻止事件的默认行为? react怎么通过dom元素,找到与之对应的 fiber对象的? onClick是在冒泡阶段绑定的? 那么onClickCapture就是在事件捕获阶段绑定的吗? 必要的知识概念 在弄清楚react事件之前,有几个概念我们必须弄清楚,因为只有弄明白这几个概念,在事件触发阶段,我们才能更好的理解react处理事件本质。 我们写在JSX事件终将变成什么? 我们先写一段含有点击事件的react JSX语法,看一下它最终会变成什么样子? class Index extends React.Component{ handerClick= (value) => console.log(value) render(){ return <div> <button onClick={ this.handerClick } > 按钮点击 </button> </div> } } 经过babel转换成React.createElement形式,如下: 最终转成fiber对象形式如下: fiber对象上的memoizedProps 和 pendingProps保存了我们的事件。 什么是合成事件? 通过上一步我们看到了,我们声明事件保存的位置。但是事件有没有被真正的注册呢?我们接下来看一下: 我们看一下当前这个元素<button>上有没有绑定这个事件监听器呢? button上绑定的事件 我们可以看到 ,button上绑定了两个事件,一个是document上的事件监听器,另外一个是button,但是事件处理函数handle,并不是我们的handerClick事件,而是noop。 noop是什么呢?我们接着来看。 原来noop就指向一个空函数。 然后我们看document绑定的事件 可以看到click事件被绑定在document上了。 接下来我们再搞搞事情😂😂😂,在demo项目中加上一个input输入框,并绑定一个onChange事件。睁大眼睛看看接下来会发生什么? class Index extends React.Component{ componentDidMount(){ console.log(this) } handerClick= (value) => console.log(value) handerChange=(value) => console.log(value) render(){ return <div style={{ marginTop:'50px' }} > <button onClick={ this.handerClick } > 按钮点击 </button> <input placeholder="请输入内容" onChange={ this.handerChange } /> </div> } } 我们先看一下input dom元素上绑定的事件 ...

December 17, 2024

中间人攻击

一句话总结:中间人攻击的关键在于获取公钥。 一、我和小美传纸条 我和隔壁班的小美互相喜欢,经常互相传纸条。但我懒得动,一般让老王帮我顺路带过去,我信任老王,所以就是简单把纸对折一下就交给老王了。 二、带锁的盒子 有一天我发现,老王居然偷看我的纸条! 我很生气,于是买了一个带锁的盒子,并配了两把钥匙🔑,我留一把,另一把让老王交给小美。我心想这下子老王没钥匙,看不了我们的纸条了。 三、一个需要两把钥匙的盒子 又过了几天,我发现老王还是会偷看,为什么呢?原来这老小子当初传递钥匙的时候,自己去复刻了一把! 于是我又想了一个办法,换了一个更高级的盒子,这个盒子必须用一对钥匙才能使用,使用公钥上锁,必须使用私钥才能打开。我委托老王把我的公钥交给小美,把小美的公钥拿给我。 以后我们都用对方的公钥来进行加密,对方用自己的私钥就能解密。而且就算老王把公钥拿去复刻一把也没关系,没有私钥他就打不开箱子,完美! 四、班主任 过了几天,我发现老王还是能偷看我们的纸条,为什么呢?????? 我想了好几天终于想明白了!原来老王当初传递钥匙的时候,他把我俩的公钥自己留下了,这老小子把自己的公钥给了我们俩。他现在有手里有四把钥匙,想看什么看什么! 这次我们终于意识到问题的关键,不管什么方案,让老王传钥匙就得坏事!于是我和小美商量好,这次不通过老王,而是通过我的班主任传递公钥,终于可以愉快的聊天了! 五、网络中的加密知识 对称加密 对称加密使用同一个密钥进行加密和解密。它的优点是速度快,它的问题是密钥传播过程中一旦泄露,就功亏一篑了。 非对称加密 非对称加密使用一对密钥:公钥和私钥。公钥用于加密,私钥用于解密。它的优点是密钥分发问题得到解决,公钥可以公开传播。缺点是速度较慢,通常用于加密小数据量或密钥交换。常见做法是通过非对称加密建立链接,交换对称加密密钥,然后使用对称加密的方式进行消息传递。 证书 数字证书是由认证机构(CA)签发的,包含公钥及其持有者身份信息的电子文档。它通过 CA 的数字签名验证其真实性,确保通信双方的身份和公钥的可信性。(证书就是上面例子中的班主任,是一个可信任的获取对方公钥的机构。) 六、中间人攻击 中间人攻击的关键在于攻击者成功获取并提供可信公钥,欺骗用户使其认为其公钥是合法服务器的公钥。这可以通过伪造证书或利用受损的 CA 来实现。(用上面例子来说,就是老王把自己的公钥伪装成小美的公钥给了我) 作为普通用户防御措施很简单,当访问一个网站时,如果浏览器弹出“证书不可信”告警的时候,不要点“我信任”。 常见考点 1. 中间人攻击的基本概念 问题: 什么是中间人攻击?请用通俗的语言解释。 中间人攻击有哪些典型的攻击方式? 被动攻击(如窃听)。 主动攻击(如数据篡改)。 中间人攻击的危害有哪些? 关键点: 中间人攻击是一种攻击者拦截并篡改通信内容的攻击。 危害包括:窃取敏感数据(如密码)、篡改通信内容、伪装身份等。 2. 中间人攻击的原理 问题: 中间人攻击是如何实现的?请简要描述其工作流程。 在 HTTP 中,为什么容易发生中间人攻击? HTTPS 是否完全能防止中间人攻击?为什么? DNS 劫持和 ARP 欺骗是如何帮助实现中间人攻击的? 关键点: 工作流程: 攻击者充当通信双方之间的“中间人”。 拦截通信数据,可能进行监听或篡改。 常见技术: ARP 欺骗:伪装网关。 DNS 劫持:将域名解析到攻击者控制的服务器。 Wi-Fi 劫持:在公共网络中拦截通信数据。 3. 防御中间人攻击的技术措施 问题: HTTPS 如何防御中间人攻击?它的安全机制是什么? 什么是证书信任链?如何防止伪造的证书? 什么是 HSTS(HTTP Strict Transport Security)?它如何防御中间人攻击? 什么是双向 SSL/TLS?它如何进一步提高安全性? 如何防止公共 Wi-Fi 中的中间人攻击? 关键点: ...

December 4, 2024

布局技巧

1、普通流(常规流) 文档流(流式布局)分为 普通流、定位流、浮动流,不同流内的块级元素和行内元素的布局方式不同,布局方式用 FC(格式化上下文,含有 块级格式化上下文、内联格式化上下文、层叠格式化上下文、灵活格式化上下文等)来命名; 普通流中的布局规则默认为块级盒子从上到下,垂直排列;内联盒子从左到右,水平排列等;(书写模式(writing-mode)会对流布局产生影响; 2、position 属性有: static:默认值,元素依然按照 普通流 的定位规则定位; relative absolute sticky fixed 使用 position 会脱离常规流,成为定位流,并有其自己的定位规则; 3、float 属性有: left right none inherit 使用 float 会脱离常规流,成为浮动流,并有其自己的定位规则; 4、table 使用 HTML 标签来布局; <table> <tr> <th></th> <th></th> </tr> <tr> <td></td> <td></td> </tr> </table> 5、flex 2009 年 W3C 提供的方案,注意只有 IE 10+ 支持 flex; 重要的概念:flex 容器,flex 项目,主轴,交叉轴; 设置某个元素的属性 display: flex;,此元素就成了 flex 容器,flex 容器内的元素是 flex 项目; flex 容器的属性: flex-direction flex-wrap flex-flow justify-content align-items align-content flex 项目的属性 flex (flex-grow、flex-shrink、flex-basis) order align-self 6、grid 二维布局方式,相对于使用 HTML 结构实现的 table 布局,grid 布局都是在 CSS 中完成的; ...

October 10, 2024

插槽

一、插槽的几种使用方式 1. 普通插槽 举例来说,这里有一个 <FancyButton> 组件,可以像这样使用: <FancyButton> Click me! <!-- 插槽内容 --> </FancyButton> 而 <FancyButton> 的模板是这样的: <button class="fancy-btn"> <slot></slot> <!-- 插槽出口 --> </button> <slot> 元素是一个 插槽出口 (slot outlet),标示了父元素提供的 插槽内容 (slot content) 将在哪里被渲染。 最终渲染出的 DOM 是这样: <button class="fancy-btn">Click me!</button> 2. 具名插槽 有时在一个组件中包含多个插槽出口是很有用的。举例来说,在一个 <BaseLayout> 组件中,有如下模板: <div class="container"> <header> <!-- 标题内容放这里 --> </header> <main> <!-- 主要内容放这里 --> </main> <footer> <!-- 底部内容放这里 --> </footer> </div> 对于这种场景, <slot> 元素可以有一个特殊的 attribute name,用来给各个插槽分配唯一的 ID,以确定每一处要渲染的内容: ...

October 4, 2024