news 2026/10/14 6:46:11

Delphi老项目连接MySQL:MyDAC 5.10源码拆解与编译定制实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Delphi老项目连接MySQL:MyDAC 5.10源码拆解与编译定制实战

简介:MySQL Data Access Components (MyDAC) v5.10 源文件包是一套面向 Delphi 7~2007 与 C++Builder 开发者的 MySQL 数据库连接组件源码,用来实现数据读写、事务控制、存储过程与异步操作,且不依赖第三方中间件,适合需要直接连接 MySQL 的桌面或服务器应用开发,覆盖从简单查询到复杂事务的常见场景。整个压缩包共 1403 个文件、1.39MB,主体为 360 个 Pascal 源文件与 33 个 C++ 源文件,另含 146 个组件包定义、107 个窗体布局、95 个工程配置以及图标位图、说明文档等,既可用于源码级定制,也可按需编译安装。目前已有 167 人学习浏览。包内目录结构清晰,自带帮助文档、FAQ、历史更新记录和许可条款,并提供了跨构建器的编译脚本,方便在 Delphi/C++Builder 中快速编译、注册组件。对于想研究数据库访问组件底层实现、或因项目需要修改扩展 MyDAC 功能的开发者,这份源文件能有效缩短二次开发周期。

1. 老 Delphi 程序连 MySQL 的刚需:为什么我要拆 MyDAC 5.10 源码

接手一套 Delphi 老项目时,最先让我上火的往往不是业务逻辑,而是数据库连接层动不动就翻车。数据表在 MySQL 里,客户端机器上那份 libmysql.dll 换一个版本,查询直接报错,换回老版本又怕安全补丁缺失。后来把目光落到 MyDAC 5.10 这套组件源码上,才算是把连接主动权拿回手里:它本身是 MySQL 访问组件的完整源码包,既能直连 MySQL,也能选择走官方客户端库,最关键的是源码在手,可以自己改、自己编,不受预编译安装包限制。这篇文章按我实际拆包验证的顺序,聊组件结构、编译安装、参数设置和排错经验,适合准备维护 Delphi 老系统、或者想深度定制数据访问层的开发者。

2. 组件包结构拆解:TMyConnection、TMyQuery 与两种连接模式怎么选

解压之后不要急着往 IDE 里装,我就是跳过这一步吃过亏。先把源码目录的层级看一眼,MyDAC 不是一个单一单元,而是一组相互依赖的组件包。至少得分清哪些是运行时包、哪些是设计时包,不然装完想拆很麻烦。

2.1 组件家族:从连接管理到批量脚本的五个常用类

这套组件里,平时真正频繁打交道的主要是五个类。TMyConnection 负责连接参数、连接生命周期和事务边界,一个工程通常只需要一个实例;TMyQuery 负责执行 SELECT 和增删改,返回数据集;TMyScript 负责一次性执行多条 SQL,初始化库表结构时很好用;TMySQLMonitor 负责记录客户端与服务端之间的通信内容,排查慢查询和莫名丢数据时最有价值;TMyDataSource 负责把 TMyQuery 接到 DBGrid、DBEdit 这一类数据感知控件上。

组件名主要职责使用频率
TMyConnection管理连接、事务、登录参数每个工程至少一个
TMyQuery查询、增删改、返回数据集日常使用最多
TMyScript批量执行多条 SQL初始化、数据迁移
TMySQLMonitor记录 SQL 与通信日志调试期常用
TMyDataSource连接 TMyQuery 与界面控件做界面绑定用

这五个类各自独立,但都依赖连接实例。拆包时最容易忽略的是 TMyDataSource:直接写代码取数据可以不关心它,但凡是拖 DBGrid 做界面的老项目,几乎都会用到。我一般先看一遍 Demos 目录里最简单的查询示例,确认当前版本这些组件在对象监视器里的属性名,再动手写业务代码,能少踩很多“属性不存在”的编译坑。

2.2 两种连接模式:直连模式与客户端库模式的原理和选型

MyDAC 最值得理解的特性是两种连接模式。第一种叫直连模式,它用组件内部自行实现的 socket 协议直接和 MySQL 服务端对话,客户端机器不需要安装 MySQL 官方客户端库,只要 3306 端口能通就能连。第二种是客户端库模式,通过 libmysql.dll 调用 MySQL 官方客户端库来完成握手、认证和协议解析。两种模式在源码里和连接参数上都有对应入口,常见做法是展开 TMyConnection 的 Options 属性,找到 Protocol 字段切换,mpDirect 对应直连,mpMySQL 对应客户端库。

选型不能只看心情。直连模式部署最简单,可执行文件丢过去就能跑,不需要额外分发 DLL,很适合给内部工具、单机版程序用;但它在 MySQL 8 之后的新认证、新压缩协议、LOAD DATA LOCAL INFILE 这类较新特性上支持有限。客户端库模式把协议细节交给官方 DLL,兼容性更好,但要求目标机器有正确版本的 libmysql.dll,而且 DLL 位数必须和程序位数一致。我自己在维护老系统时默认用直连模式,只有在需要新认证或复杂传输特性时才切到客户端库模式,并且把 DLL 和 exe 放在同一目录,避免系统目录里的旧版本干扰。

2.3 解压后先看哪几个目录:一份可对照的文件清单

源码包解压之后的目录结构,直接影响你能不能一次装成功。常见结构是按 IDE 版本分目录,因为不同 Delphi 版本的包格式和编译器指令不一样。我习惯先看 Source 目录,再确认 Demos 目录里有没有对应版本的示例工程。

路径常见内容用途
Source\Delphi7对应 IDE 的运行时包与设计时包编译生成 bpl / dcu
Source\Delphi2009对应版本代码旧版本 IDE 安装
Source\DelphiXE后续版本代码新一点的环境
Demos示例工程与连接配置照抄连接参数最快
Docs帮助文档、版本说明查属性说明

这里最容易搞错的是 Delphi 7 和 Delphi 2009 的目录不能混用。曾经有同事图省事,把 Delphi 2009 目录下的 dpk 拿给 Delphi 7 编译,结果报了一堆 Pascal 语法不兼容。源码包里的版本目录基本是按编译器语法特性划分的,跨版本硬编可以碰运气,但不值得浪费时间。我先按目标 IDE 选好目录,然后把对应目录加进 IDE 的 Library Path,再开始编译安装。

3. 从源码编译安装:Delphi 环境里的安装步骤与定制的三个入口

拿到源码包之后,接下来要解决的是怎么把这堆 pas 文件变成 IDE 里能拖拽的组件。这个过程说简单也简单,说坑也多,核心是掌握编译顺序和路径设置。

3.1 设计期安装:先编译运行时包,再注册设计时包

安装 MyDAC 源码包的正确顺序,是先编译运行时包,再编译并注册设计时包。运行时包提供实际功能代码,生成的是 bpl 和 dcu;设计时包负责把组件注册到 IDE 的组件面板上,它依赖运行时包。常见步骤是这样:

  1. 关闭 Delphi,备份当前 IDE 的 bpl 配置和 Library Path;
  2. 用文件管理器打开 Source 下对应 IDE 版本的目录;
  3. 先打开不带 dcl 前缀的 dpk 文件,执行 Build,确认生成 bpl;
  4. 再打开带 dcl 前缀的 dpk 文件,执行 Build,然后点 Install;
  5. 重启 IDE,在 Component > Install Packages 里勾选新注册的包,组件面板出现 My 开头的组件页。

如果你更习惯命令行,也可以写一个批处理来做,我一般这样写:

@echo off rem 以 Delphi 7 为例,其他版本请替换 dcc32 路径和目录名 set MYDAC_SRC=D:\libs\MyDAC5.10\Source\Delphi7 set D7_BIN=C:\Delphi7\bin rem 1. 先编运行时包 "%D7_BIN%\dcc32.exe" -B -Q "%MYDAC_SRC%\MyDAC70.dpk" if errorlevel 1 goto fail rem 2. 再编设计时包 "%D7_BIN%\dcc32.exe" -B -Q "%MYDAC_SRC%\dclMyDAC70.dpk" if errorlevel 1 goto fail echo 编译完成,请到 IDE 中执行 Install goto end :fail echo 编译失败,先检查 Library Path 是否包含 Source 目录 :end

这段批处理的核心是 -B 参数,它表示全量重建,避免旧的 dcu 缓存干扰;-Q 是安静模式,只输出错误信息。注意 dcc32.exe 是 Delphi 7 自带的命令行编译器,新版 IDE 的命令行工具名称可能不同,要按实际环境替换。运行时包和设计时包的先后顺序不能反,否则设计时包会提示找不到运行时单元的符号。

除了编译顺序,还要在 IDE 的 Environment Options 里把 Source 对应目录加进 Library Path。我遇到过编译通过、但打开窗体时提示找不到 TMyConnection 的情况,原因就是 bpl 装了,但 IDE 搜索路径里没有 pas 文件,设计器无法解析类声明。把这个目录加进去再重启 IDE,问题就消失了。

3.2 离线编译:不装组件面板,只把源码当库用

有些内部构建机器上不跑 Delphi IDE,只需要在命令行环境里编出业务 exe。这时候不需要装设计时包,只要让编译器能找到源码单元就行。常见做法是把 Source 对应目录写进项目搜索路径,然后在工程文件里引用需要的单元。这样做组件不会出现在面板上,但运行时对象照常工作,适合自动构建和版本管理。

我一般在持续集成脚本里做两件事:一是把 dcu 输出目录固定到项目下的 Library 子目录,方便清理;二是把 Search Path 指向源码目录,而不是复制 pas 到工程目录。复制源码虽然能编过,但后续要换版本时很容易误用旧文件,排查起来非常痛苦。离线编译时如果报找不到某个单元,优先检查搜索路径里是否把 Source 的所有子目录都包含了,MyDAC 源码里有些公共单元放在根目录,有些放在对应版本目录,漏一个都会编译失败。

3.3 定制入口:默认端口、默认字符集和认证切换改在哪里

源码包最大的价值是能改默认行为。我不建议每次在窗体上手动设置十几个属性,而是直接改组件默认值,让所有新放置的组件从一开始就带着正确配置。

第一个入口是默认端口。TMyConnection 的构造函数里通常会有 Port 的初始赋值,常见值是 3306。如果公司内部 MySQL 跑在 3307,业务又必须统一连接端口,就可以把这个默认值改掉。改的时候顺手在代码里加注释,不然半年后你自己也不知道端口为什么变了。

第二个入口是字符集。老代码里中文乱码的根源,往往是组件默认 Charset 为空、UseUnicode 为 False。我会在构造函数里把默认值改成 utf8mb4 和 True:

constructor TMyConnection.Create(AOwner: TComponent); begin inherited Create(AOwner); Port := 3306; Options.Charset := 'utf8mb4'; Options.UseUnicode := True; end;

这段代码说明三点:Port 是连接端口,Charset 控制连接建立后发送的字符集声明,UseUnicode 决定字符串字段是否按 Unicode 处理。第三个值很关键,只改 Charset 不改 UseUnicode,读出来的中文仍可能乱码。注意这里直接改构造函数会影响所有实例,如果你有多个环境需要不同端口,就别把 Server 也写死,只改默认值即可。

第三个入口是认证切换,针对 MySQL 8 场景。旧源码里认证协商逻辑往往只认 mysql_native_password,遇到 caching_sha2_password 会直接失败。常见做法有两个方向:一是服务端把用户切回旧插件;二是找到源码里发送握手响应的位置,把客户端声明的插件名改成服务端支持的插件。第二个方向工作量大,需要同时处理密码加密方式,我一般优先用服务端切换,风险更小。

4. 避坑实录:安装、连接与字符集翻车后的排查笔记

无论源码包多完整,实战中踩坑都在所难免。这里记录几条我反复遇到、且每条都能直接照抄解决方法的排查笔记。

4.1 组件装完面板空白,窗体上还提示找不到 TMyConnection

现象:设计时包安装提示成功,但组件面板上找不到 TMyConnection,打开旧窗体时提示“Class TMyConnection not found”。

原因:最常见的两个原因:一是运行时包没有先装,设计时包加载时找不到底层类;二是不同 IDE 版本的包混装,Delphi 7 的 bpl 被拖到新版 IDE 里注册,类名冲突或无法解析。

解决:先确认安装的是当前 IDE 对应的 Source 版本目录,然后在 Component > Install Packages 里把旧的 MyDAC 包移除,重新按“运行时包先编、设计时包后编”的顺序来一遍。装完重启 IDE,在组件面板里右键找到 My 开头的页签,确认组件已经注册。

4.2 localhost 连接被拒:10061 错误其实和代码无关

现象:使用 Conn.Connect 时报“Can't connect to MySQL server on 'localhost' (10061)”,但同一台机器上用命令行 mysql 能正常登录。

原因:Windows 上 localhost 可能解析成 IPv6 地址 ::1,而 MySQL 服务端配置只监听了 127.0.0.1。TMyConnection 把 Server 设为 localhost 后,走的却是 IPv6,服务端根本不听这个端口。这不是组件问题,是地址解析问题。

解决:先把 Server 改成 127.0.0.1 试一次。如果必须用主机名,检查 MySQL 的 bind-address 配置是否包含对应监听地址。验证监听状态可以用这条命令:

netstat -ano | findstr :3306

如果输出里只有[::]:3306而没有0.0.0.0:3306,说明服务端只监听 IPv6,需要调整 my.ini 的 bind-address 为 0.0.0.0 或 127.0.0.1。从那以后我新建连接先把 Server 写成 IP,不写 localhost,省掉这块来回折腾的时间。

4.3 中文字段乱码:Charset 和 UseUnicode 必须一起设置

现象:程序里插入中文正常,SELECT 出来的中文在 DBGrid 里显示成问号;或者 Navicat 里看数据是好的,程序读出来是乱码。

原因:连接建立后没有发送正确的SET NAMES utf8mb4,服务端按 latin1 处理客户端传输的字符;同时 UseUnicode 为 False 时,字符串字段被当作 AnsiString 处理,数据在两层转换中丢失。

解决:连接前设置两个参数,缺一不可:

Conn.Options.Charset := 'utf8mb4'; Conn.Options.UseUnicode := True;

如果用的是旧版本组件,Charset 属性没接上,可以在 AfterConnect 事件里手动兜底:

Conn.ExecSQL('SET NAMES utf8mb4');

执行完之后再查一遍字符集,确认 client 和 results 都是 utf8 相关值:

SELECT @@character_set_client, @@character_set_results;

如果结果里出现 latin1,说明连接参数没生效,回到前面的设置去查,别在数据转换代码里找问题。

4.4 libmysql.dll 位数与版本不匹配导致闪退

现象:本机调试正常,把 exe 复制到另一台机器后直接闪退,或者弹“Cannot load libmysql.dll”。

原因:用的是客户端库模式,但目标机器没有 libmysql.dll,或者程序是 32 位的,却放了一个 64 位的 DLL。Windows 加载 DLL 时位数不匹配不会给友好提示,通常直接让进程退出。

解决:先确认你的 Delphi 程序编译目标是 32 位还是 64 位,再去找对应位数的 libmysql.dll,放在 exe 同目录。不要指望放在 system32 里,exe 目录优先级更高,而且 system32 目录下容易混入旧版本。如果业务用不到新协议特性,最简单是切回直连模式,直接去掉 DLL 依赖。

4.5 MySQL 8 认证插件 caching_sha2_password 连接失败

现象:MySQL 服务端是 8.0,用户默认认证插件是 caching_sha2_password,MyDAC 5.10 连接时报“Authentication plugin 'caching_sha2_password' cannot be loaded”。

原因:MyDAC 5.10 时代 MySQL 8 还没发布,源码里的认证协商逻辑不认识这个新插件。握手时客户端无法按服务端要求完成密码交换。

解决:短期方案是在 MySQL 里把该用户临时切回旧插件:

ALTER USER 'test'@'%' IDENTIFIED WITH mysql_native_password BY '密码';

这个方案在 MySQL 8.0 上还能用,但新版 MySQL 已经逐步禁用旧插件,所以不能把希望全押在这条路上。更好的做法是换用较新的客户端库文件,并把 Protocol 切到客户端库模式,让新 DLL 里的认证逻辑去处理。如果源码里有清晰的握手处理函数,也可以根据服务端发来的插件名增加分支,但工作量不小,适合真有必要时再做。

5. 落地一个可运行的查询工程:组件放置、连接串与调试三板斧

避坑说到底是为了让业务跑起来。这一章给一个最小可用的工程骨架,覆盖连接、查询、批量执行和调试四个刚需场景。

5.1 最小连接样例:TMyConnection 与 TMyQuery 跑通一条查询

先放一个最基本的按钮事件,做的事情是:创建连接、打开数据库、查询最近 20 条记录、逐行往 Memo 里输出。代码里刻意避免在设计期放组件,用运行时创建方式,这样更容易看出每个参数的作用。

procedure TForm1.Button1Click(Sender: TObject); var Conn: TMyConnection; Q: TMyQuery; begin Conn := TMyConnection.Create(nil); try Conn.Server := '127.0.0.1'; Conn.Port := 3306; Conn.Username := 'appuser'; Conn.Password := 'apppass'; Conn.Database := 'appdb'; Conn.Options.Charset := 'utf8mb4'; Conn.Options.UseUnicode := True; Conn.Connect; Q := TMyQuery.Create(nil); try Q.Connection := Conn; Q.SQL.Text := 'SELECT id, title, create_time ' + 'FROM articles ' + 'WHERE status = :st ' + 'ORDER BY create_time DESC LIMIT 20'; Q.Params.ParamByName('st').AsInteger := 1; Q.Open; while not Q.Eof do begin Memo1.Lines.Add(Q.FieldByName('title').AsString); Q.Next; end; finally Q.Free; end; finally Conn.Free; end; end;

这里几个参数要说明:Server 填 127.0.0.1 而不是 localhost,能避开 IPv6 解析问题;Charset 和 UseUnicode 成对出现,保证中文不乱码;Q.Open 只用于 SELECT,如果是 INSERT 或 UPDATE,要改成 Q.ExecSQL。使用:st参数是为了避免拼 SQL 时的注入和转义问题,每次执行前用 ParamByName 赋值。注意 Q.Next 循环读取时,如果数据量大,要考虑 FetchAll 的设置,默认情况下边取边读会占用连接,循环期间不要在同一连接上执行其他查询。

5.2 TMyScript 批量执行与事务边界控制

初始化数据库、导入脚本这类场景,逐条执行 SQL 太慢。TMyScript 的作用就是把多条 SQL 一次发给服务端处理。但要注意它只负责执行,不负责原子性,事务仍要自己控制。

procedure RunBatchScript(Conn: TMyConnection); var Sc: TMyScript; begin Sc := TMyScript.Create(nil); try Sc.Connection := Conn; Sc.SQL.Text := 'INSERT INTO log_audit(user_name, action) VALUES (''dev'', ''login'');' + 'UPDATE t_user SET last_login = NOW() WHERE id = 2;'; Sc.Execute; finally Sc.Free; end; end;

TMyScript 默认按分号切分语句,所以每条 SQL 之间必须有分号。如果脚本里包含存储过程定义,BEGIN...END 结构里的分号会被误判为语句边界,这是 5.10 版本常见的解析限制。遇到这种情况,我一般把 CREATE PROCEDURE 拆出来用单独连接执行,或者改用 TMyQuery 逐条执行。

需要保证多条 SQL 要么全成功、要么全失败时,要额外套事务:

Conn.StartTransaction; try // 执行第一条 SQL // 执行第二条 SQL Conn.Commit; except Conn.Rollback; raise; end;

注意先确认 TMyConnection 的 AutoCommit 属性。如果 AutoCommit 为 True,组件会在每条语句执行后自动提交,事务控制不会生效。我一般把 AutoCommit 设为 False,由代码显式控制提交时机。

5.3 使用 TMySQLMonitor 抓取 SQL 日志

连接正常、查询结果不对、或者想知道某条 SQL 到底在什么时候执行,靠断点单步太慢。MyDAC 自带的 TMySQLMonitor 组件可以直接把客户端发出的 SQL 写到日志文件,配置很轻量:

SQLMonitor := TMySQLMonitor.Create(nil); try SQLMonitor.FileName := ExtractFilePath(Application.ExeName) + 'sql_trace.log'; SQLMonitor.Active := True; Conn.Monitor := SQLMonitor; finally // 连接销毁时由 Owner 统一释放 end;

这样每次 TMyQuery 执行,SQL 语句会连同执行时间写入日志。日志文件里的内容能直观看出:参数值有没有正确传入、字符集声明有没有在连接后自动执行、哪条语句耗时最长。需要注意,TMySQLMonitor 组件在不同版本里的属性名略有出入,我说的是 5.10 源码包里的常见用法,如果编译时提示找不到 Monitor 属性,去 Demos 目录里找对应的 MonitorDemo 看一遍挂接方式就行。

日志文件别一直开着,调完就关闭 Active,否则程序在生产环境持续写文件,磁盘空间会悄悄被占满。

6. 验证自检与进阶改造:把 5.10 源码改到能连 MySQL 8

最后分享一个我每次拆完源码包都会下意识做的动作:写一个最小的自检函数,验证“连接、字符集、事务回滚”三件事是否正常。这个函数能筛掉大部分环境问题。

6.1 一个自检函数:三分钟确认连接环境

function CheckMyDACSetup(Conn: TMyConnection; out Msg: string): Boolean; var Q: TMyQuery; begin Result := False; Q := TMyQuery.Create(nil); try Q.Connection := Conn; Q.SQL.Text := 'SELECT @@character_set_client, @@character_set_results'; Q.Open; if (Pos('utf8', Q.Fields[0].AsString) = 0) or (Pos('utf8', Q.Fields[1].AsString) = 0) then begin Msg := 'charset error: ' + Q.Fields[0].AsString; Exit; end; Result := True; Msg := 'ok'; finally Q.Free; end; end;

这个函数在 Conn.Connect 成功后调用。如果返回 charset error,说明前面设置的 Options.Charset 没有生效,按第 4 章乱码排查的方向继续查。如果这里正常,后续中文显示还有问题,那问题就在界面数据感知控件或数据库表的排序规则上,方向完全不同。

6.2 连 MySQL 8 前的四项核对清单

服务端如果是 MySQL 8,我建议在业务代码之前先核对四件事。第一,确认用户插件类型,执行SELECT user, host, plugin FROM mysql.user,看目标用户是不是 caching_sha2_password。第二,确认客户端库文件的位数和版本,32 位程序必须配 32 位 DLL。第三,确认程序里 Protocol 用的是直连还是客户端库,这决定了前两项哪一个真正生效。第四,确认连接后字符集查询结果是 utf8mb4 而不是 latin1。

这四项核对完,5.10 源码包连 MySQL 8 的兼容性问题基本都能定位到具体层。剩下的无非是换 DLL、换用户插件、或者改代码里认证协商,不会再是“玄学”。

6.3 我给自己定的固定动作

从那以后,我每次拿到这类组件源码包,都强制走一遍固定顺序:先原包编译安装,再做一次最小连接自检,然后只改动一个默认参数,重新编译回归。这个顺序能保证构建环境的问题和代码改动的问题不混在一起。很多人一上来就改源码,编译不过就怀疑包有问题,其实八成是 IDE 路径没配好。先让原包跑通,再动定制,排查效率会高很多。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 6:45:50

蛇形方阵入门:模拟算法与方向数组的经典实战

P5731 蛇形方阵,是我刷题时见过的特别适合练“模拟”的入门题之一。题面很干脆:给一个正整数 n,要求输出一个 nn 的方阵,数字从 1 开始,像蛇一样从外圈一圈一圈往里面盘。比如 n4 时,结果是这样&#xff1a…

作者头像 李华
网站建设 2026/10/14 6:45:28

AIGC创作训练营深度拆解:从提示词到工作流的技能成长指南

1. 为什么“闪学”模式火了:训练营背后的需求逻辑今年以来,身边越来越多非技术背景的朋友开始问同一个问题:AI到底怎么用来赚钱或者提升工作效率?这个问题看起来简单,但真要系统回答,往往会把人绕晕。大模型…

作者头像 李华
网站建设 2026/10/14 6:44:53

树莓派+GPIO:从零搭建家庭能耗监控面板

这篇博文需要你提供具体的项目信息才能开工。目前四个输入参数——项目标题、项目正文、关键词、摘要描述——都是空的,我没法凭空捏造一个项目出来,那样写出来的东西既不符合你的需求,也违背了我做内容的原则。请把真实要写的标题、原始素材…

作者头像 李华
网站建设 2026/10/14 6:44:46

Cookie安全四大配置项:Secure、HttpOnly、SameSite与Domain实战指南

1. 为什么今天还必须聊Cookie安全——它不是“小饼干”,而是身份凭证的裸奔现场你有没有遇到过这样的情况:刚在某购物平台下单付款,转头就收到几条精准到商品型号的推销短信;或者登录一个老账号时,系统突然提示“检测到…

作者头像 李华
网站建设 2026/10/14 6:44:30

S7-1200 PLC流水灯控制系统设计与仿真全流程实战解析

流水灯这题目,乍看像是单片机课的入门作业,但放到PLC里做,味道完全不一样。最近好几份《可编程控制器原理与应用》的综合实验报告都选了“基于S7-1200的PLC流水灯控制系统设计与仿真”这个题目。我接手这类问题时发现,它几乎把S7-…

作者头像 李华
网站建设 2026/10/14 6:44:26

JSON转Sketch:手写插件实现设计稿自动化导入与生成

简介:面向Sketch设计师与前端开发者的实验性插件json-sketchapp,可将JSON文件直接转换为Sketch可编辑的设计文件,解决从数据源快速生成UI设计稿、实现设计自动化的问题。压缩包共9个文件,以JSON配置、JavaScript脚本为主&#xff…

作者头像 李华