LOADING

加载过慢请开启缓存 浏览器默认开启

耀耀切克闹

WEB前端基础知识梳理(三)

前端随笔 2025/7/15

v-model的实现原理

v-model 的核心原理可以概括为:

  • 将数据通过属性绑定到表单元素的 value/checked 等属性上
  • 监听表单元素的 input/change 等事件
  • 在事件处理函数中更新数据
  • 通过 Vue 的响应式系统实现视图和数据的同步

computed和watch的区别和应用场景

  • computed是一个计算属性,根据依赖的数据进行计算,并返回计算结果。computed适用于一个数据受多个数据影响的场景。如按钮的禁用属性的控制

  • watch是一个监听器,监听数据的变化并执行相应的操作。适用于一个数据影响多个数据的场景。例如:异步操作

  • computed可以进行缓存,watch不能。watch可以异步操作,computed不能异步操作

    请解释一下JavaScript中的this关键字的工作原理,并举例说明。

    在JavaScript中,this关键字是一个非常重要的概念,它代表了函数运行时的上下文(context)。this的值取决于函数是如何被调用的,而不是如何被定义的。

  • 1.’全局上下文’: 在全局执行上下文,this指向的是全局对象

  • 2.’函数上下文’: 在函数内部,this的值取决于函数是如何被调用的

  • 3.’箭头函数’: 箭头函数不绑定自己的this,它们继承自父级执行上下文中的this

  • 4.this的值可以被 call和appply先式的设置

    BFC是什么,如何创建一个Bfc

    BFC是web页面中一个隔离的渲染区域,它决定元素如何对其内容进行定位,以及与其他元素的关系和相互作用。

    BFC的主要作用:

  • 1.清除浮动:当容器内的元素设置为float,并且没有设置高度时,容器的高度会塌陷。通过创建BFC,可以阻止容器的高度塌陷

  • 2.阻止外边距合并:在垂直方向上,相邻的两个元素的边距(margin)会发生合并。通过创建 BFC,可以阻止外边距合并。

  • 3.隔离样式:BFC 内部的样式不会影响到外部,反之亦然
    创建BFC的常见方法:

  • 1.设置元素的display属性为inline-block、table-cell等

  • 2.设置元素的position属性为absolute或者fixed

  • 3.overflow的属性为hidden、auto或scroll

  • 4.设置元素的float为left或right

前端工程化是什么

前端工程化 是指将前端开发过程中的各种任务(如代码编写、构建、部署等)进行标准化、自动化和模块化的过程。它的目标是提高开发效率,保证代码质量,以及方便团队协作。

前端工程化通常包括以下几个方面:

  1. 脚手架工具:用于快速创建项目结构和初始代码,如 create-react-app、vue-cli、angular-cli 等。
  2. 构建工具:用于自动化构建过程,如代码压缩、打包、编译等。常见的构建工具有 Webpack、Gulp、Grunt 等。
  3. 模块打包工具:用于将多个模块打包成一个或多个文件,如 Webpack、Rollup、Parcel 等。
  4. 代码规范和格式化工具:用于统一代码风格,如 ESLint、Prettier 等。
  5. 自动化测试工具:用于自动化测试,如 Jest、Mocha、Selenium 等。
  6. 版本控制工具:用于代码版本管理和协作开发,如 Git。
  7. 持续集成/持续部署(CI/CD) :用于自动化测试和部署,如 Jenkins、Travis CI、GitHub Actions 等。
  8. 代码文档化工具:用于生成代码文档,如 JSDoc、TypeDoc 等。

请解释JavaScript中的原型链(Prototype Chain)是如何工作的,以及它如何实现继承。

原型链(Prototype Chain) 是 JavaScript 中对象继承的基础机制。每个对象在创建时都会有一个内部属性,称为 [[Prototype]],在浏览器中通常可以通过 __proto__ 属性访问。这个内部属性指向创建该对象构造函数的 prototype 属性。当试图访问一个对象的属性时,如果该对象本身没有这个属性,JavaScript 就会在这个对象的原型(也就是它的构造函数的 prototype)中寻找。如果原型中也没有找到,那么 JavaScript 就会继续在原型的原型中寻找,这就形成了所谓的原型链。

原型链继承 是通过将子类的原型指向父类的实例来实现的。这样,子类的实例不仅可以访问自身的属性和方法,还可以访问父类实例的属性和方法。以下是一个简单的原型链继承的例子:

function Parent() {
  this.name = 'parent';
}

function Child() {
  this.age = 10;
}

Child.prototype = new Parent();

var child1 = new Child();
console.log(child1.name); // 输出 'parent'

在这个例子中,Child 的原型被设置为了 Parent 的一个实例,因此 Child 的实例 child1 可以访问到 Parent 的属性 name。

异步编程:请解释JavaScript中的事件循环(Event Loop)和宏任务(Macrotasks)与微任务(Microtasks)的区别,并举例说明

事件循环(Event Loop) 是 JavaScript 的执行环境用于管理执行代码、收集和处理事件以及执行子任务的机制。它是一个不断运行的过程,用于协调同步代码和异步代码的执行。

在事件循环中,同步任务会立即执行,而异步任务会被放入任务队列中。异步任务分为微任务(Microtasks)和宏任务(Macrotasks)。

  • 微任务(Microtasks):微任务队列中的任务会在当前事件循环的同步任务执行完毕后立即执行。常见的微任务包括 Promise.then/catch/finally、MutationObserver、process.nextTick(在Node.js中)等。

  • 宏任务(Macrotasks):宏任务队列中的任务会在当前事件循环的同步任务和微任务执行完毕后执行。常见的宏任务包括 setTimeout、setInterval、I/O、UI渲染等。

事件循环的执行顺序如下:

  1. 执行全局上下文的同步代码。
  2. 执行所有的微任务,直到微任务队列为空。
  3. 执行一个宏任务。
  4. 重复步骤2和步骤3。

框架/库:请比较Vue.js 2.x 和 Vue.js 3.x 的主要区别,包括性能改进、新特性等。

  1. 响应式系统:Vue 3 使用了基于 Proxy 的响应式系统,代替了 Vue 2 中的基于 Object.defineProperty 的系统。Proxy 能够直接监听对象和数组的变化,并且不需要对每个属性进行转换,这使得 Vue 3 的响应式系统更加高效和易于理解。

  2. 打包体积:Vue 3 的核心库体积更小,这是因为 Vue 3 进行了模块化重构,将一些功能移到了外部库中,如路由(Vue Router)、状态管理(Vuex)和测试工具(Vue Test Utils)。这样,用户可以根据需要选择性地引入所需的功能,从而减小最终构建的体积。

  3. 性能优化:Vue 3 引入了静态树和静态属性标记,这意味着在虚拟 DOM 的 diff 算法中,可以跳过那些没有发生变化的静态节点,从而提高性能。Vue 3 还使用了动态数组规划来优化虚拟 DOM 的重写和更新过程。

  4. 编译优化:Vue 3 的模板编译器生成了更高效的渲染函数,这些渲染函数可以更好地利用 JavaScript 引擎的优化,从而提高运行时性能。

  5. 组合式 API:Vue 3 引入了组合式 API,这是一种更灵活的编写组件的方式,使得逻辑复用和代码组织更加方便。这与 Vue 2 中的选项式 API(data, methods, computed, watch 等)形成了对比。

  6. 其他新特性:Vue 3 还引入了 Teleport(用于将子组件渲染到 DOM 的其他部分)、Fragments(允许组件有多个根节点)、自定义渲染器 API 等。

状态管理:请解释什么是前端状态管理,并比较Vuex和Redux的主要区别和适用场景。

前端状态管理 是指在复杂的前端应用中,将组件之间共享的状态(如用户信息、主题设置、应用配置等)集中管理,以避免状态在组件间的不必要传递和同步问题。状态管理库提供了维护、更新和访问应用状态的方法,并且通常包含一些额外的功能,如中间件支持、时间旅行、热重载等。

Vuex 是 Vue.js 的官方状态管理库,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 的核心概念包括:

  • State:定义了应用状态的数据结构,可以在这里存储数据。
  • Getters:允许组件从 Store 获取状态,可以认为是 store 的计算属性。
  • Mutations:是唯一允许更新应用状态的方法,它们用于执行同步操作。
  • Actions:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
  • Modules:允许将 store 分割成模块(module),每个模块拥有自己的 state、mutation、action、getter,甚至是嵌套子模块。

Redux 是另一个流行的前端状态管理库,主要用于 React 应用。Redux 的核心概念包括:

  • Store:存储整个应用的状态。
  • Action:描述了发生了什么的普通对象。
  • Reducer:指定了应用状态的变化如何响应 actions 并返回新的状态。
  • Middleware:用于在 dispatch() 和 reducer 之间扩展 Redux 的功能。

Redux 和 Vuex 在概念上非常相似,都提供了集中式状态管理,但它们的实现和使用方式有所不同。Redux 有更严格的数据流,而 Vuex 提供了一些更高级的功能,如模块化和插件系统。

代码分割和懒加载:请解释代码分割(Code Splitting)和懒加载(Lazy Loading)的概念,以及它们在前端工程中的应用。

代码分割(Code Splitting) 是一种前端优化技术,它允许开发者将代码分成多个小块(chunks),然后根据需要加载这些小块。代码分割的主要目的是减少首次加载页面时所需加载的代码量,从而加快首次加载时间,并提升用户体验。代码分割通常与模块打包工具(如 Webpack、Rollup 和 Parcel)一起使用,这些工具支持将代码分割成不同的块,并在运行时按需加载。

懒加载(Lazy Loading) 是另一种优化技术,它指的是仅在需要时才加载资源。懒加载常用于图片、视频和其他媒体内容,以及在用户滚动到页面的某个部分时才加载该部分的代码。这样可以减少初始加载时间,节省带宽,并提升性能。

代码分割和懒加载都是现代前端应用中常用的性能优化技术。代码分割更多关注于结构和模块化,而懒加载更多关注于按需加载资源。两者可以结合使用,以实现更高效的应用加载和执行。

服务端渲染(SSR) :请解释什么是服务端渲染(SSR),以及它相比客户端渲染(CSR)的优点和缺点。

SSR是一种在服务端完成页面渲染的技术。在这种模式下,服务器接收客户端的请求后,会根据请求数据和模板文件生成完整的HTML页面,然后将这个页面发生给客户端。这样用户,就可以看到完成的内容,无需等待js加载和执行。

优点:

  1. 首屏加载速度快:由于服务器已经生成了完整的HTML页面,因此客户端可以直接显示这个页面,无需等待JavaScript加载和执行。
  2. SEO友好:搜索引擎爬虫可以很好地解析由服务器生成的HTML页面内容,有利于SEO优化。
  3. 适合复杂页面:对于包含大量数据、需要复杂计算的页面,SSR可以更好地处理并减少客户端的负载。

缺点:

  1. 服务器压力大:对于每个请求,服务器都需要重新渲染页面,这可能导致服务器压力过大。
  2. 开发限制:SSR要求开发者在编写Vue组件时,需要考虑到服务器端和客户端环境的差异,不能过度依赖客户端环境。
  3. 调试困难:SSR的调试过程相对复杂,需要同时考虑到服务器端和客户端的日志和错误信息。

Web安全:请解释什么是跨站脚本攻击(XSS),以及如何防范XSS攻击。

XSS(跨站脚本攻击,Cross-Site Scripting)是一种常见的网络安全威胁,它允许攻击者在用户的浏览器中执行恶意脚本。以下是关于 XSS 攻击和预防措施的补充信息:

XSS 攻击 通常发生在当应用程序不正确地处理用户输入时,攻击者可以在网页中注入恶意脚本。这些脚本会在其他用户浏览该网页时执行,可能导致数据泄露、会话劫持或其他恶意行为。

预防 XSS 攻击的措施包括:

  1. 转义 HTML:将用户输入中的 HTML 特殊字符(如 <、>、&、"、' 等)转义为它们的 HTML 实体(如 &lt;、&gt;、&amp;、&quot;、&apos; 等),以防止浏览器将其解释为 HTML 代码。

  2. 使用安全的框架:一些现代的 web 框架(如 React、Vue 和 Angular)内置了防止 XSS 攻击的机制,它们会自动转义用户输入的 HTML 特殊字符。

  3. 设置 HTTP 头部 CSP:内容安全策略(Content Security Policy,CSP)是一个额外的安全层,它帮助检测和缓解某些类型的攻击,包括 XSS 和数据注入攻击。通过设置合适的 CSP 规则,可以限制资源(如脚本、图片等)的加载来源,从而减少 XSS 攻击的风险。

  4. 使用验证和清理库:使用专门的库来验证和清理用户输入,如 DOMPurify 或 Google 的 Caja。

  5. 避免内联脚本和事件处理器:尽量避免在 HTML 中直接使用内联脚本和事件处理器,而是使用外部脚本文件,并通过框架的数据绑定机制来处理用户交互。

  6. 模板引擎的正确使用:大多数模板引擎都提供了自动转义的功能,确保在渲染变量到 HTML 时自动转义 HTML 特殊字符。

阅读全文

css——笔记记录

前端随笔 2025/5/20

1.说说你对css盒模型的理解

css盒模型:浏览器在进行页面布局渲染时,将所有的元素表示为一个个矩形盒子,每一个盒子包含4个部分:content,padding,border,margin
其中我们一般写的width和height这两属性其实是content的几何属性。
标准盒模型和怪异盒模型(IE盒模型)

标准盒模型:width+padding+margin+border 这是一般的和模型计算宽度的方式

怪异盒模型:width(width+padding+border)+margin IE浏览器在编写v8引擎的时候觉得宽度就应该包括了padding和border

可以通过box-sizing切换盒子模型:

  • box-sizing:border-box;(要求浏览器以IE盒模型来加载容器)
  • box-sizing:content-box;(要求浏览器以标准盒模型来加载容器)

2.css中的选择器有哪些?说说优先级

  • id选择器
  • 类名选择器
  • 标签选择器
  • 后代选择器
  • 子元素选择器
  • 相邻兄弟选择器
  • 群组选择器
  • 属性选择器
  • 伪元素选择器
  • 伪类选择器

优先级:!import>内联>id选择器>类名选择器>标签选择器

3.css中的长度单位有哪些?

  • px:像素。1px等于屏幕上1个像素点的大小
  • rem:相对长度单位,相对于根元素字体的大小
  • em:相对长度单位,相对于父元素字体大小的长度单位
  • vw:相当于视窗宽度百分比的长度单位,1vw等于视窗宽度的
  • vh:相当于视窗高度百分比的长度单位,1vh
  • %: 相对于父元素尺寸的百分比长度单位。若父元素宽度为100px,那么子元素宽度为100%等于100px

4.css中有哪些方式可以隐藏页面的元素?区别是什么?

  • display:none; 脱离文档流,无法响应事件,回流重绘
  • visibility:hidden; 占据文档流,无法响应事件,只重绘不回流
  • opacity:0; 占据文档流,可以响应事件
  • position: absolute;top:-9999px;left:-9999px;将元素移出页面的可见范围,使其看起来不可见。无法响应事件
  • transform:scale(0); 将元素缩小为0,使其看起来不可见,设置pointer-events: none;后不会去响应事件。

5.谈谈你对BFC的理解

BFC指的是块级格式化上下文,是CSS中用于决定块级元素如何进行布局的一种规则。

在CSS中,元素要么遵循BFC规则,要么遵循IFC(Inline Formatting Context)规则,这两种规则是 mutually exclusive的,即一个元素不可能同时遵循这两种规则。

BFC的布局规则如下:

  1. 遵照从上往下从左往右的布局排列
  2. 浮动元素会参与BFC的布局
  3. BFC容器内的子元素的margin-top不会和BFC这个父容器发生重叠

BFC的产生主要是为了解决在某些情况下,块级元素内部子元素的margin、padding等属性对父元素产生影响的问题。在BFC中,内部的Box会在垂直方向上根据margin的值进行排列。即使有浮动元素也是如此。

一个元素要成为BFC,需要满足以下条件之一:

  1. 该元素是一个块级元素,如<div>、<p>等。
  2. 该元素的position属性值为relative、absolute或fixed。
  3. 该元素的float属性值不为none。
  4. 该元素是一个表格单元格(<td>或<th>)或表格行(<tr>)并且overflow属性值不为visible。
  5. 该元素是block-level表单元素(如<input>、<textarea>等),并且overflow属性值不为visible。

6.水平垂直居中的方式有哪些?

1.使用position属性配合transform进行居中

position: absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);

2.使用弹性布局

display: flex;
justify-content: center;
align-items: center;

3.使用grid布局

display: grid;
justify-items:center;
align-items:center;
height:100%;

7.css3新增了哪些属性?

  • 选择器:属性选择器。伪元素伪类
  • box-shadow
  • 背景裁剪:background-clip
  • transition 过渡动画
  • transform 旋转,平移,缩放,倾斜等
  • animatuin 纯动画
  • 渐变色

8.css、sass、less

CSS(层叠样式表)、Sass 和 Less 都是用于定义网页样式的工具,但它们在语法和功能上有一些区别。下面是它们的主要区别:

CSS

CSS 是最基本的样式定义语言,用于描述 HTML 或 XML(包括如 SVG、XUL 这类 XML 分支语言)文档的外观和格式。CSS 的语法简单明了,由选择器(selector)和声明块(declaration block)组成。

示例:

body {
  background-color: lightblue;
}

h1 {
  color: navy;
  margin-left: 20px;
}

Sass

Sass(Syntactically Awesome Stylesheets)是一种 CSS 预处理器,它扩展了 CSS 的语法,提供了许多有用的功能,如变量、嵌套规则、混合(mixins)、继承等。Sass 有两种语法:缩进式的 .sass 语法和括号式的 .scss 语法。

示例(.scss 语法):

$primary-color: navy;

body {
  background-color: lightblue;
}

h1 {
  color: $primary-color;
  margin-left: 20px;
}

示例(.sass 语法):

$primary-color: navy

body
  background-color: lightblue

h1
  color: $primary-color
  margin-left: 20px

Less

Less 也是一种 CSS 预处理器,它与 Sass 类似,提供了变量、嵌套规则、混合(mixins)、运算等特性。Less 的语法更接近于 CSS,因此对于熟悉 CSS 的开发者来说,Less 的学习曲线相对较低。

示例:

@primary-color: navy;

body {
  background-color: lightblue;
}

h1 {
  color: @primary-color;
  margin-left: 20px;
}

主要区别

  1. 语法:

    • CSS 是原生语言,没有预处理器特性。
    • Sass 有两种语法:缩进式的 .sass 和括号式的 .scss。
    • Less 的语法与 CSS 非常相似,但增加了预处理器特性。
  2. 功能:

    • CSS 本身不支持变量、嵌套规则、混合等高级功能。
    • Sass 和 Less 都扩展了 CSS,提供了变量、嵌套规则、混合、继承、运算等高级功能。
  3. 使用场景:

    • 对于简单的项目或不需要高级功能的场景,直接使用 CSS 即可。
    • 对于复杂的项目或需要更高效、更可维护的样式代码,Sass 和 Less 都是很好的选择。

11.重排(回流)和重绘

重排(回流)

重排是指浏览器重新计算页面元素的位置和尺寸,并进行布局的过程。当以下情况发生时,会触发重排:

  1. 添加或删除可见的 DOM 元素。
  2. 元素尺寸改变(宽度、高度等)。
  3. 内容变化,如文本变化。
  4. 浏览器窗口尺寸变化。
  5. 计算或获取某些属性,如 offsetWidth、scrollHeight 等。

重排是一个相对昂贵的操作,因为它涉及到整个页面或部分页面的布局更新。为了减少重排的次数,可以尽量批量修改样式,或者使用 documentFragment、requestAnimationFrame 等技术。

重绘(Repaint)

重绘是指浏览器将元素的外观更新到屏幕上的过程。当以下情况发生时,会触发重绘:

  1. 样式变化,但不影响布局,如颜色、背景色、边框等。
  2. 元素可见性变化,如 visibility、opacity 等。

重绘的成本低于重排,因为它只需要将新的样式应用到已有的元素上,而不需要重新计算布局。

10.居中为什么要使用transform(为什么不使用marginLeft/Top)

transform 属于合成属性(composite property),对合成属性进行 transition/animation 动画将会创建一个合成层(composite layer),这使得被动画元素在一个独立的层中进行动画。通常情况下,浏览器会将一个层的内容先绘制进一个位图中,然后再作为纹理(texture)上传到 GPU,只要该层的内容不发生改变,就没必要进行重绘(repaint),浏览器会通过重新复合(recomposite)来形成一个新的帧。

top/left属于布局属性,该属性的变化会导致重排(reflow/relayout),所谓重排即指对这些节点以及受这些节点影响的其它节点,进行CSS计算->布局->重绘过程,浏览器需要为整个层进行重绘并重新上传到 GPU,造成了极大的性能开销。

11.CSS3中transition和animation的属性分别有哪些

transition 过渡动画:

  • (1) transition-property:属性名称
  • (2) transition-duration: 间隔时间
  • (3) transition-timing-function: 动画曲线
  • (4) transition-delay: 延迟

animation 关键帧动画:

  • (1) animation-name:动画名称
  • (2) animation-duration: 间隔时间
  • (3) animation-timing-function: 动画曲线
  • (4) animation-delay: 延迟
  • (5) animation-iteration-count:动画次数
  • (6) animation-direction: 方向
  • (7) animation-fill-mode: 禁止模式
阅读全文

公众号下的页面换了域名,需要注意的事项

前端随笔 2025/4/20
  1. 支付授权目录:

    • 在微信公众平台中,找到“微信支付”设置,更新“支付授权目录”。这个目录应该包含新的域名,因为用户点击支付按钮后,微信会跳转到这个目录下的页面进行支付操作。
  2. 接口安全域名:

    • 如果新的域名也需要调用微信的API接口,那么您还需要在“开发设置”中更新“接口安全域名”,确保新的域名在微信的安全域名列表中。
  3. 业务域名:

    • 如果您的公众号使用了JS-SDK,并且新的域名下有前端页面需要调用JS-SDK,那么您还需要在“公众号JS-SDK”页面更新“业务域名”。
  4. 服务器配置:

    • 如果新的域名下有服务器地址用于接收微信的事件消息,那么您还需要在“开发设置”中更新“服务器配置”,包括服务器地址(URL)、Token、EncodingAESKey和消息加解密方式。
  5. SSL证书:

    • 如果新的域名使用了不同的服务器或服务提供商,您可能需要重新上传或更新SSL证书,以确保HTTPS连接的安全性。
  6. 代码中的域名引用:

    • 您还需要检查并更新代码中所有硬编码的旧域名引用,确保所有请求都指向新的域名。

在更新配置后,请务必进行充分的测试,以确保支付功能和其他相关功能在新的域名下能够正常工作。测试内容包括但不限于支付流程、接口调用、消息接收等。

请注意,所有配置的域名必须使用HTTPS协议,并且需要具有有效的SSL证书。

阅读全文

微信小程序配置主题、按钮颜色等

前端随笔 2025/3/20

一、在utils下新建文件globalPage.js 其作用如下

  1. 自动设置全局数据:在页面加载时,自动将一些全局数据(如主题数据、系统信息等)设置到当前页面。

  2. 提供主题更新方法:通过 setThemeChange 方法,可以在页面中方便地更新主题数据。

    module.exports = function (app) {
    const originalPage = Page;
    Page = function (config) {
     const {
       onLoad
     } = config;
     config.onLoad = function (onLoadOptions) {
       if (typeof onLoad === 'function') {
         this.setData({
           themeData: app.globalData.themeData,
         })
         onLoad.call(this, onLoadOptions)
       }
     }
     config.setThemeChange = function (){
       this.setData({
         themeData: app.globalData.themeData
       })
     }
     return originalPage(config)
    }
    }
    

    二、在app.js中写对应方法,配合globalPage.js,将数据存储在全局中

  3. 获取主题:

    • 使用 setTimeout 模拟异步获取主题数据的过程。在实际应用中,你可以使用 wx.request 或其他网络请求方法来获取主题数据。
  4. 构建主题字符串:

    • themes 对象包含了各种主题颜色的键值对。
    • 使用 for...in 循环遍历 themes 对象,将每个键值对转换成 CSS 变量的字符串格式,并存储在 themeString 中。
  5. 存储主题数据:

    • 将构建好的 themeString 存储在 globalData.themeData 中,以便在整个应用中访问。
  6. 通知应用更新主题:

    • 调用 noticeSetThemes 方法,通知应用更新主题样式。这个方法需要你在 App 实例中定义,用于更新应用的样式。
const globalPage = require('utils/globalPage.js');
  //globalData: {
 //  themeData:'',
 // },
 
// 通知应用更新主题
  noticeSetThemes: function () {
    let pages = getCurrentPages();
    if (pages.length >= 1) {
      pages.forEach(item => {
        item.setThemeChange(this.globalData.themeData)
      })
    }
  },
// 模拟获取主题接口
  async getTheme() {
    setTimeout(() => {
      const themes = {
        '--main-color': '#3D7770',
        '--sub-color':'#bada55',
        '--page-background-color':'#f6f1eb',
      }
  
      let themeString = ''
      for (let key in themes) {
        themeString += `${key}: ${themes[key]}; `
      }
      this.globalData.themeData = themeString
      this.noticeSetThemes()
    }, 200)
  },

三、具体使用

在wxml文件

最顶级view标签

    <view style="{{themeData}}">
    .....
    </view>

完成以上步骤,那么wxss文件就可以使用css变量来使用

.button {
    color:var(--main-color)
}
阅读全文

漏洞扫描——react项目源代码泄漏

前端随笔 2025/1/13

安全部门对我们前端项目进行漏洞扫描发现,前端有一个React项目生产环境源代码泄漏,解决过程的记录

1、React项目源代码泄漏

安全部门给我们的描述是:公网系统源代码泄露 。漏洞详情:没有正确配置,导致项目源码泄露

定位到问题:

image.png

2、为什么出现了项目源码泄漏

这是因为source-map,源映射的原因:

在前端开发中,源映射(Source Maps)是一种将压缩或编译后的代码映射回源代码的技术。这使得开发者可以在调试时查看原始的、未压缩的代码,而非难以阅读的生产环境代码。

在许多构建工具和框架中(例如 Create React App),process.env.GENERATE_SOURCEMAP 是一个环境变量,用于控制是否生成源映射文件。当你将 process.env.GENERATE_SOURCEMAP 设置为 ‘false’ 时,构建工具将不会生成对应的源映射文件。

如果源映射文件存在,用户或恶意攻击者可以使用它们轻松地调试和查看原始源代码。这可能会导致源代码的某些私有逻辑和实现细节暴露,从而带来潜在的安全风险。

3、解决方式

React项目在需要将环境变量GENERATE_SOURCEMAP设置为false

process.env.GENERATE_SOURCEMAP = 'false';

然后编译打包上传服务器,可以看到已经解决了源代码泄漏的问题
企业微信截图\_17364046515706.png

设置为 false 的影响

  • 不生成源映射:当设置 process.env.GENERATE_SOURCEMAP 为 ‘false’,构建过程将禁用源映射的生成。这意味着在生产环境中用户无法访问源映射文件,阻止了他们查看源代码。
  • 代码可读性:虽然在调试过程中,没有源映射可能使得错误更难追踪,但在生产环境中保护源代码是更为重要的。
  • 提高安全性:通过不生成源映射,减小了源代码被分析和利用的风险。

当设置 process.env.GENERATE_SOURCEMAP 为 ‘false’ 时,你可以减轻源代码泄漏的风险,因为用户无法获得源映射文件,从而无法轻松地查看原始代码。

阅读全文

nginx重启&解决端口冲突

前端随笔 2024/11/29

前言

测试环境突然不能访问了,经排查最开始发现是nignx没进程了,于是我觉得重启下nignx就行了。重启后发现还是不行,看nginx重启的端口中9090有好多使用的,感觉是端口冲突,处理了端口冲突后,测试环境可以使用了。记录一下本次处理

1.查看nginx进程
ps -ef | grep nignx
image.png

2.如果没有nginx进程,就需要重启nginx服务,进入nginx所在目录,去重启ginx服务

cd /opt/nginx/

sudo service nginx restart

3.重启后发现还是不行,查看是否是端口冲突了

image.png
4.确实是端口冲突了,找到端口冲突逻辑,删除冲突端口对应的pid

sudo lsof -i:9090

发现是primetheu进程导致的,其pid为7252
image.png

5.将prometheu关闭,再删除冲突端口对应的pid进程

systemctl stop prometheus.service

sudo lsof -i :9090

sudo kill -9 7252

6.再重启nginx

sudo service nginx restart

阅读全文

HTTP了解一下

前端随笔 2024/11/1

一、什么是HTTP? HTTP 和 HTTPS 的区别?

1.HTTP

HTTP (HyperText Transfer Protocol),即超文本运输协议。是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。

HTTP常被用于在Web浏览器和网站服务器之间传递信息,以明文方式发送内容,不提供任何方式的数据加密

特点如下:

  • 支持客户/服务器模式
  • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快
  • 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记
  • 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间
  • 无状态:HTTP协议无法根据之前的状态进行本次的请求处理

2.HTTPS

HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。

因为HTTP 以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。因此,HTTP 不适合传输敏感信息,比如:资金账户、密码等。为了解决 HTTP 的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议 HTTPS,为了数据传输的安全,HTTPS 在 HTTP 的基础上加入了 SSL 协议,即 HTTPS = HTTP + SSL/TLS,通过 SSL证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

SSL的实现这些功能主要依赖于三种手段:

  • 对称加密:采用协商的密钥对数据加密

  • 非对称加密:实现身份认证和密钥协商

  • 摘要算法:验证信息的完整性

  • 数字签名:身份验证

  • 首先客户端通过URL访问服务器建立SSL连接

  • 服务端收到客户端请求后,会将网站支持的证书信息(证书中包含公钥)传送一份给客户端

  • 客户端的服务器开始协商SSL连接的安全等级,也就是信息加密的等级

  • 客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站

  • 服务器利用自己的私钥解密出会话密钥

  • 服务器利用会话密钥加密与客户端之间的通信

3.区别

  • HTTPS是HTTP协议的安全版本,HTTP协议的数据传输是明文的,是不安全的,HTTPS使用了SSL/TLS协议进行了加密处理,相对更安全
  • HTTP 和 HTTPS 使用连接方式不同,默认端口也不一样,HTTP是80,HTTPS是443
  • HTTPS 由于需要设计加密以及多次握手,性能方面不如 HTTP
  • HTTPS需要SSL,SSL 证书需要钱,功能越强大的证书费用越高

二、OSI七层模型

image.png

应用层

应用层位于 OSI 参考模型的第七层,其作用是通过应用程序间的交互来完成特定的网络应用

该层协议定义了应用进程之间的交互规则,通过不同的应用层协议为不同的网络应用提供服务。例如域名系统 DNS,支持万维网应用的 HTTP 协议,电子邮件系统采用的 SMTP协议等

在应用层交互的数据单元我们称之为报文

表示层

表示层的作用是使通信的应用程序能够解释交换数据的含义,其位于 OSI参考模型的第六层,向上为应用层提供服务,向下接收来自会话层的服务

该层提供的服务主要包括数据压缩,数据加密以及数据描述,使应用程序不必担心在各台计算机中表示和存储的内部格式差异

会话层

会话层就是负责建立、管理和终止表示层实体之间的通信会话

该层提供了数据交换的定界和同步功能,包括了建立检查点和恢复方案的方法

传输层

传输层的主要任务是为两台主机进程之间的通信提供服务,处理数据包错误、数据包次序,以及其他一些关键传输问题

传输层向高层屏蔽了下层数据通信的细节。因此,它是计算机通信体系结构中关键的一层

其中,主要的传输层协议是TCP和UDP

网络层

两台计算机之间传送数据时其通信链路往往不止一条,所传输的信息甚至可能经过很多通信子网

网络层的主要任务就是选择合适的网间路由和交换节点,确保数据按时成功传送

在发送数据时,网络层把传输层产生的报文或用户数据报封装成分组和包,向下传输到数据链路层

在网络层使用的协议是无连接的网际协议(Internet Protocol)和许多路由协议,因此我们通常把该层简单地称为 IP 层

数据链路层

数据链路层通常也叫做链路层,在物理层和网络层之间。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层协议

在两个相邻节点之间传送数据时,数据链路层将网络层交下来的 IP数据报组装成帧,在两个相邻节点间的链路上传送帧

每一帧的数据可以分成:报头head和数据data两部分:

  • head 标明数据发送者、接受者、数据类型,如 MAC地址
  • data 存储了计算机之间交互的数据

通过控制信息我们可以知道一个帧的起止比特位置,此外,也能使接收端检测出所收到的帧有无差错,如果发现差错,数据链路层能够简单的丢弃掉这个帧,以避免继续占用网络资源

物理层

作为OSI 参考模型中最低的一层,物理层的作用是实现计算机节点之间比特流的透明传送

该层的主要任务是确定与传输媒体的接口的一些特性(机械特性、电气特性、功能特性,过程特性)

该层主要是和硬件有关,与软件关系不大

参考文献

HTTP和HTTPS的区别 - 简书 (jianshu.com)

HTTP与HTTPS的区别 - konglingbin - 博客园 (cnblogs.com)

二、OSI七层模型

OSI 7层模型和TCP/IP 4层模型 - 知乎 (zhihu.com)

阅读全文

js基础回顾

前端随笔 2024/8/30

javaScripit的数据类型

基本数据类型:number、bigint、string、null、undefined、boolean、symbol

引用数据类型:array、object、function 本质上都是object

js的引用数据类型和基本数据类型的区别

1.存储位置不同

基本数据类型:直接存储在栈(stack)中的简单数据段

引用数据类型:以 地址:数据 的映射关系来进行存储,地址存放在栈内存中。数据实体存放在堆内存中。

什么是栈?什么是堆?

栈是一种线性数据结构,遵循先进后出的原则,用于存储简单数据结构。
堆是一种用于动态内存分配的数据结构,用于存储复杂的数据结构和对象。

js如何判断数据类型?

1.typeof
typeof主要用来检测一个变量是不是基本数据类型(null除外, typeof null的结果是object)
如果用typeof检测引用数据类型基本判断的都是object,typeof function判断的结果是function。

2.instanceof:通过查找原型链来检测某个变量是否为某个类型数据的实例

 const a = [0, 1, 2];
        console.log(a instanceof Array); // true
        console.log(a instanceof Object); // true

        const b = {name: 'xx'};
        console.log(b instanceof Array); // false
        console.log(b instanceof Object); // true

3.Object.prototype.toString.call()方法来揭示类型
每种引用类型都会直接或间接继承自Object类型,因此它们都包含toString()函数。不同数据类型的toString()类型返回值是不一样的,所以通过toString()函数可以准确判断值的类型。

Es6新增的语法

  • 1.模版字符串
  • 2.解构赋值
  • 3.let和const
  • 4.默认参数
  • 5.扩展运算符
  • 6.类(class)
  • 7.模块化 (export关键字导出模块,import关键字导入模块)
  • 8.promise
  • 9.Generator
  • 10.箭头函数
  • 11.for of

let、const、var的区别

  • 1.var声明的变量存在变量提升,let和const没有(在声明前使用会报错)
  • 2.var声明的变量可以多次声明,后面声明的会覆盖前面的,let和const不允许在相同作用域重复声明
  • 3.let和const是块级作用域(只要块级作用域内存在let命令,这个区域不受外包影响),var是受外部影响的。
  • 4.var和let可以修改声明的变量,const不行,但对于引用数据类型,可以修改其里面的属性值,内存地址是无法修改的

    箭头函数this指向

1.所有函数在执行时,会创建一个函数执行上下文,普通函数的执行上下文中会有一个变量this,而箭头函数不会创建自己的this对象只会继承在自己作用域的上一层的this

2.箭头函数没有自己的this,所以箭头函数中的this的指向在它定义时就已经确定了,之后不会改变。

数组常用方法

arr.push() 向数组末尾添加
arr.pop() 数组末尾删除
arr.shift() 数组头部删除
arr.unshift() 向数组头部添加
arr.join(',') 数组以什么形式分隔
arr.sort() 数组排序
arr.splice(1,2,'1') 在指定位置删除指定个数元素再增加任意个数元素 (实现数组任意位置的增删改)
arr.concat(arr2) 合并arr和arr2两数组
arr.toString() 数组转字符串,本质是内部调用了arr.join()
arr.valueOf()  返回数组的值
arr.indexOf() 查询某个元素第一次出现的位置,存在返回该元素下标,不存在返回-1
arr.lastIndexOf() 反向查询某个元素第一次出现的位置
arr.includes() 检查数组中有没有某个值

数组迭代方法

arr.forEach()  遍历数组,每次循环中执行传入的回调函数
arr.map()  遍历数组,每次循环中执行传入的回调函数,需要有返回值,据回调函数的返回值,生成一个新的数组
arr.some()  遍历数组,判断某个元素是否满足条件
arr.every() 遍历数组,判断所有元素都满足条件
arr.find() 遍历数组,执行回调函数,回调函数执行一个条件,返回满足条件的第一个元素,不存在返回undefined
arr.findIndex() 遍历数组,执行回调函数,回调函数接受一个条件,返回满足条件的第一个元素下标,不存在返回-1
arr.reduce()  (归并)遍历数组, 每次循环时执行传入的回调函数,回调函数会返回一个值,将该值作为初始值prev,传入到下一次函数中,返回的最终操作结果
arr.reduceRight() 同上reduce,不过是从右往左

字符串的方法

str.concat(str2,str3) 连接字符串
str.indexof() 搜索指定字符位置
str.lastIndexOf() 搜索指定字符最后1一次出现的位置
str.replace('wo','ni') 字符串替换wo替换为ni
str.slice(2,4) 取字符串的某个部分,返回一个新的字符串。
str.subString(2,7) 截取两下标之间的字符,修改的是原字符串,slice是生成新字符串
str.substr(start,length) 返回的字符串包含从 start的length个字符
str.split(',') 字符串转数组,根据xx分隔
str.trim() 从一个字符串的两端删除空白字符
str.includes('xx') 检查字符串是否包含指定的字符,有为true,反之false
str.toLowerCase() 字符转小写
str.toUpperCase() 字符转大写
str.endsWith()  检查字符串是否已指定字符串结束,是返回true,反之
str.repeat(2) 将字符串复制指定次数 

对象常用的实例方法

Object.create(pro,obj) : 创建一个对象

Object.assign(target,...obj) : 浅拷贝,可以合并对象

Object.defineProperty(obj, prop, descriptor) : 添加或修改一个自有属性并返回对象

Object.keys() : 返回给定对象自身key组成的数组

Object.values(): 返回给定对象自身value组成的数组

Object.freeze(obj) : 冻结对象,对象不可改变

Object.entries(obj) : 返回对象键值对数据

Object.getPrototypeOf(obj) : 返回对象原型

Object.is(value1, value2) : 判断两个值是否相等,约等于 ===

object.defineProperty和Proxy都是怎么实现数据代理的

Object.defineProperty()方法可以用来定义一个对象的属性,并为其设置一个getter或setter函数。当访问或修改该属性时,会自动调用这些函数。通过这种方式,可以实现对数据的读取和修改进行控制。

Proxy对象可以用来创建一个代理对象,该代理对象会拦截对原始对象的读取和修改操作,并将其转发到原始对象上。通过这种方式,可以实现对数据的读取和修改进行控制。

怎么理解promise的

promise是异步编程的一种解决方案

promise仅有三种状态:pending(进行中)、rejected(失败)、fulfilled(成功)

promise的使用:

promise
.then(result => {···})  //状态发生改变时
.catch(error => {···}) // 指定发生错误时的回调函数
.finally(() => {···}); // 不管promise最后的状态,都执行

promise.all()

Promise.all()方法用于将多个 Promise实例,包装成一个新的 Promise实例

实例p的状态由p1、p2决定,分为两种:

  • 只有p1、p2的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数
  • 只要p1、p2之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数

注意,如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

promise.race()

promise.race()方法同样是将多个promise实例,包装成一个新的promise实例,只要其中一个实例状态变化就跟着改变,例如设置图片超时时间

//请求某个图片资源
function requestImg(){
    var p = new Promise(function(resolve, reject){
        var img = new Image();
        img.onload = function(){
           resolve(img);
        }
        //img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg"; 正确的
        img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg1";
    });
    return p;
}

//延时函数,用于给请求计时
function timeout(){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('图片请求超时');
        }, 5000);
    });
    return p;
}

Promise
.race([requestImg(), timeout()])
.then(function(results){
    console.log(results);
})
.catch(function(reason){
    console.log(reason);
});

bind()、call()和apply()

  • 三者都可以改变函数的this对象指向
  • 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window
  • 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入
  • bind是返回绑定this之后的函数,apply、call 则是立即执行

事件循环

js里的所有任务都可以分为同步任务和异步任务,同步任务一般会直接进入主执行栈中,异步任务则是进入一个任务队列中,当主线程里的同步任务执行完了,会去任务队列里读取异步任务推入主线程执行。异步任务队列不只有一个,分为宏任务和微任务,当主线程来读取异步任务队列时,会先将所有微任务依次执行完,再去执行宏任务,期间有其他任务进入也是按上面规则,如此循环形成事件循环

常见的微任务:promise.then(),promise.catch(),process.nextTick

常见的宏任务:setTimeOut等定时器事件、postMessage

原型和原型链

原型:每个函数都有一个特殊的属性叫做原型prototype,该原型prototype有一个自有属性construct,这个属性指向该函数。还有一个_proto_属性,该属性指向的是构造函数的原型。

原型链:当在实例化的对象中访问一个属性时,首先会在该对象内部(自身属性)寻找,如找不到,则会向其__proto__指向的原型中寻找,如仍找不到,则继续向原型中__proto__指向的上级原型中寻找,直至找到或Object.prototype.__proto__为止(值为null),这种链状过程即为原型链。

js中如何实现继承的

js中常见的继承方式:
原型链继承、构造函数继承(call)、组合继承、原型式继承(Object.creat()实现的是浅拷贝)、寄生组合继承

e56中extends 的语法糖和寄生组合继承的方式基本类似

阅读全文
1 ... 2 3 4 ... 9
avatar
耀耀切克闹

欢迎来到耀耀切克闹的博客

不是因为是主角才成功,而是成功了才成为主角

想要的都拥有,得不到的都释怀