Qt嵌入式开发中ASCII与HEX的工程化转换实战
1. 为什么“ASCII转HEX”不是个简单查表题——从串口调试到固件烧录的真实战场你有没有在Qt Creator里盯着串口助手发呆发出去一串“ATRST”设备却只回了个乱码或者用Keil5生成.hex文件后拿去ESP32烧录时提示“校验失败”反复核对地址偏移却找不到错在哪又或者在VS Code里调试OpenOCD项目看到内存窗口里一长串0x41 0x54 0x2B 0x52 0x53 0x54脑子瞬间卡死——这到底是“ATRST”还是别的什么这些场景背后藏着一个被严重低估的基础能力ASCII与HEX之间不是单向翻译而是双向映射、带上下文约束的工程动作。它不等于背下ASCII码对照表就能通关而是在Qt界面设计、嵌入式固件解析、CAN总线报文构造、网络协议调试等真实环节中必须实时、无损、可逆地完成字节级转换。我做过三年Qt工业上位机开发也带过五个ESP32物联网项目最常被实习生问的问题不是“怎么写信号槽”而是“为什么我用QString::toHex()出来的结果和Keil生成的.hex文件头对不上”——答案从来不是“你代码写错了”而是“你没搞清HEX在这里代表什么是内存镜像的十六进制表示是串口传输的ASCII编码序列还是CAN帧里的原始字节流”本文不讲教科书定义只拆解你在Qt Designer拖控件、在esp-idf里写AT指令、在Keil5里看反汇编、在VS Code里解析.elf转.hex时真正要动手敲的那几行关键代码、要避开的三个致命陷阱、以及为什么Qt的QByteArray::toHex()默认加空格而Keil的.hex格式绝对不允许空格。所有内容基于实测Qt 5.15.2 esp-idf v4.4 Keil MDK-ARM v5.37环境每一步都踩过坑、改过bug、验证过波形。2. ASCII与HEX的本质差异不是字符vs数字而是编码层vs表示层很多人把“ASCII转HEX”理解成“把字母A变成0x41”这没错但太浅。真正卡住工程师的是混淆了数据本体data entity和数据表示data representation两个层面。举个Qt里最典型的例子你用QSerialPort发送字符串Hello底层实际发出的是5个字节0x48 0x65 0x6C 0x6C 0x6F。这5个字节是数据本体它们在内存里就是这5个值。而当你用Qt Creator的串口助手显示接收到的数据时它默认以ASCII字符形式呈现即显示为Hello但你点开“十六进制视图”它又显示为48 65 6C 6C 6F——注意这里没有0x前缀也没有空格就是纯十六进制数字串。这个“48 65 6C 6C 6F”就是数据表示是人类可读的HEX格式。问题来了如果你把这个HEX字符串“48656C6C6F”直接发给设备设备收到的是8个ASCII字符4,8,6,5,6,C,6,F对应字节是0x34 0x38 0x36 0x35 0x36 0x43 0x36 0x46完全不是你想发的0x48 0x65 0x6C 0x6C 0x6F。这就是第一层混淆HEX字符串 ≠ HEX字节流。前者是文本后者是二进制。再看Keil5生成的.hex文件它本质是Intel HEX格式一种带地址、校验、记录类型的文本文件。里面一行:10010000214601360121470136012148013601216E开头的:是固定标识10是数据长度16字节0100是地址00是记录类型后面21460136...才是真正的16字节数据的HEX表示。这里每个21、46都是一个字节的HEX表示但整个文件是文本格式需要解析器如ST-Link Utility把它还原成内存镜像。而esp-idf里esp_rom_md5_hash()计算的MD5值输出的是32字符HEX字符串如9e107d9d372bb6826bd81d3542a419d6这是标准MD5摘要的文本表示要转成字节数组就得每两个字符解析一次。所以所谓“转换”核心是明确目标你要的是字节序列的HEX文本表示用于日志、配置、UI显示还是HEX文本的字节序列还原用于烧录、解析、加密Qt的QByteArray::toHex()默认返回无分隔符的HEX字符串如48656c6c6f但如果你传参toHex( )就变成48 65 6c 6c 6f——后者在串口助手里看着舒服但粘贴到Keil的“Memory Window”里会报错因为Keil只认连续HEX串。这就是第二层混淆HEX表示的格式约定。不同工具链对HEX字符串的格式要求天差地别Qt Designer里QLineEdit输入HEX常允许空格或0x前缀Keil的.hex文件严格按Intel HEX规范每行有校验和CAN总线工具要求HEX字符串必须是偶数长度、无空格、大写而Python的binascii.unhexlify()则要求输入必须是偶数长度、仅含0-9 a-f A-F。不厘清这个光写QString::fromUtf8(data).toHex()在Qt里能跑通在烧录ESP32时就会失败。3. Qt环境下的实操方案从QByteArray到QDataStream的四层穿透在Qt项目里实现ASCII/HEX转换绝不能只靠QString::toHex()。我见过太多人用QByteArray::fromStdString(ATRST).toHex()得到41542b525354然后直接发给QSerialPort结果设备无响应——因为设备期望的是ASCII字符流而你发的是HEX字符串的字节流。正确路径必须分层穿透。下面以Qt 5.15.2 MinGW 7.3.0环境实测为例给出四套方案覆盖从简单UI到复杂协议的全部场景。3.1 基础层QByteArray的原生转换适合日志显示与简单调试这是最常用也最容易出错的一层。QByteArray提供两个核心方法toHex()将字节数组转为HEX字符串默认无分隔符。fromHex()将HEX字符串可含空格、0x前缀转回字节数组。// 场景在Qt Designer的QTextEdit里显示串口接收的HEX QByteArray rawData port-readAll(); // 假设收到0x48 0x65 0x6C 0x6C 0x6F QString hexStr rawData.toHex( ); // 注意传入空格作为分隔符得48 65 6c 6c 6f ui-textEditLog-append(HEX: hexStr); // 场景用户在QLineEdit里输入HEX字符串如48 65 6C要发给设备 QString inputHex ui-lineEditHex-text().trimmed(); QByteArray sendBytes QByteArray::fromHex(inputHex.toLatin1()); // toLatin1()确保ASCII安全 if (sendBytes.isEmpty()) { QMessageBox::warning(this, 错误, HEX格式无效请检查是否为偶数长度且只含0-9A-F); return; } port-write(sendBytes); // 发送的是字节流不是HEX字符串提示QByteArray::fromHex()对输入极其宽容能自动过滤空格、0x、冒号等非十六进制字符但要求总长度为偶数。如果用户输入486奇数长度fromHex()返回空数组这是静默失败必须主动校验。3.2 协议层QDataStream处理结构化数据适合自定义协议与固件解析当你的Qt上位机要解析ESP32上传的传感器数据包如2字节温度2字节湿度1字节校验就不能用字符串拼接必须用QDataStream按字节序精准读取。这时HEX转换退居二线核心是字节序控制。// 假设ESP32发来一包数据0x00 0x1A 0x00 0x28 0x32 温度26℃湿度40%校验0x32 QByteArray packet port-readAll(); if (packet.size() 5) return; QDataStream stream(packet, QIODevice::ReadOnly); stream.setByteOrder(QDataStream::BigEndian); // ESP32默认大端 quint16 temp, humi; quint8 checksum; stream temp humi checksum; // 自动按2/2/1字节读取 // 验证校验和temphumi低8位应等于checksum if ((static_castquint8(temp humi) 0xFF) ! checksum) { qDebug() 校验失败丢弃数据; return; } // 转HEX显示用于调试 qDebug() 原始包HEX: packet.toHex().toUpper(); // 001A002832 qDebug() 解析温度: temp ℃, 湿度: humi %;注意QDataStream的setByteOrder()必须与设备端一致。ESP32的xtensa架构默认大端但某些AT固件可能用小端务必查文档。这里packet.toHex().toUpper()是调试用实际业务逻辑绝不依赖HEX字符串。3.3 文件层解析Intel HEX格式适配Keil/STM32烧录场景Keil5生成的.hex文件不是纯HEX而是Intel HEX格式。Qt里没有内置解析器必须手写。核心是按行解析提取数据段。以下代码已通过Keil MDK-ARM v5.37生成的.hex文件实测bool parseIntelHex(const QString filePath, QMapquint32, QByteArray memoryMap) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return false; QTextStream in(file); while (!in.atEnd()) { QString line in.readLine().trimmed(); if (line.isEmpty() || line[0] ! :) continue; // 跳过空行和非记录行 // Intel HEX格式:LLAAAATTDDCC // LL数据长度, AAAA地址, TT记录类型, DD数据, CC校验和 if (line.length() 11) continue; // 最短记录:020000020000EA bool ok; int len line.mid(1, 2).toInt(ok, 16); if (!ok || len * 2 11 line.length()) continue; quint32 addr line.mid(3, 4).toInt(ok, 16); if (!ok) continue; quint8 type static_castquint8(line.mid(7, 2).toInt(ok, 16)); if (!ok) continue; if (type 0) { // 数据记录 QString dataStr line.mid(9, len * 2); QByteArray data QByteArray::fromHex(dataStr.toLatin1()); memoryMap.insert(addr, data); } else if (type 1) { // 文件结束记录 break; } } file.close(); return !memoryMap.isEmpty(); } // 使用示例加载.hex到QByteArray用于烧录 QMapquint32, QByteArray memMap; if (parseIntelHex(output.hex, memMap)) { // memMap现在包含所有地址段可合并为连续镜像 QByteArray firmware; for (auto it memMap.begin(); it ! memMap.end(); it) { firmware.append(it.value()); } qDebug() 固件大小: firmware.size() 字节; }关键细节Intel HEX的校验和是256 - (LL AAAA高字节 AAAA低字节 TT 所有DD字节) mod 256但Qt上位机通常不校验只提取数据。这里省略校验逻辑专注转换主干。3.4 高级层QVariant与自定义类型注册适配Qt Quick与QML在Qt Quick项目中QML无法直接操作QByteArray需通过QVariant暴露。这时HEX转换要封装成属性// 在C类中定义 Q_PROPERTY(QString hexString READ hexString WRITE setHexString NOTIFY hexStringChanged) public: QString hexString() const { return m_data.toHex( ).toUpper(); } void setHexString(const QString hex) { QByteArray newBytes QByteArray::fromHex(hex.toLatin1().replace( , )); if (newBytes ! m_data) { m_data newBytes; emit hexStringChanged(); } } private: QByteArray m_data;// QML中使用 TextField { text: myCppObject.hexString onAccepted: myCppObject.hexString text }实测陷阱QML TextField的onAccepted在回车时触发但用户可能输入0x48 0x65replace( , )后变成0x480x65fromHex()会失败。解决方案是预处理hex.replace(0x, ).replace( , )。4. 嵌入式侧的硬核实践esp-idf中的HEX与ASCII互转陷阱在esp-idf v4.4环境下HEX/ASCII转换常出现在AT指令解析、OTA固件校验、BLE特征值读写三大场景。这里没有Qt的便利API全是裸指针和标准库一个疏忽就内存越界。4.1 AT指令中的ASCII流 vs HEX命令ESP32的AT固件如ESP-IDF AT版本支持两种模式普通ASCII模式和HEX模式。普通模式下ATRST直接发送ASCII字节HEX模式下需发送ATHEX1启用之后所有指令都用HEX字符串发送如ATRST要发41542B525354。但注意HEX模式只影响指令不影响响应。响应永远是ASCII。这就要求你的Qt上位机必须动态切换发送模式。// esp-idf中判断当前模式伪代码实际需解析AT响应 char *at_response OK; if (strstr(at_response, HEX MODE ON)) { // 启用HEX模式后续指令需转HEX char hex_cmd[13]; // ATRST共6字符HEX后12字符1结尾 ascii_to_hex(ATRST, hex_cmd); esp_at_send_cmd(hex_cmd); // 发送HEX字符串 } else { esp_at_send_cmd(ATRST); // 发送ASCII字符串 } // ascii_to_hex实现安全版防溢出 void ascii_to_hex(const char *src, char *dst) { const char hex_chars[] 0123456789ABCDEF; size_t len strlen(src); for (size_t i 0; i len; i) { uint8_t byte (uint8_t)src[i]; dst[i*2] hex_chars[byte 4]; dst[i*2 1] hex_chars[byte 0x0F]; } dst[len*2] \0; }踩坑实录早期版本esp-at固件在HEX模式下若发送ATGMR获取版本响应是ASCII但如果你的Qt程序误以为响应也是HEX用QByteArray::fromHex()去解析就会得到空数组导致超时重试。解决方案维护一个状态机记录当前AT会话模式。4.2 OTA固件校验HEX字符串的MD5与CRC32ESP32 OTA升级时常需比对固件的MD5或CRC32校验值。esp-idf提供esp_rom_md5_hash()但输出是16字节二进制需转HEX字符串供Qt上位机显示。// esp-idf中计算固件MD5 uint8_t md5_result[16]; esp_rom_md5_hash(firmware_data, firmware_len, md5_result); // 转HEX字符串安全避免sprintf溢出 char md5_str[33] {0}; // 32字符1结尾 for (int i 0; i 16; i) { sprintf(md5_str i*2, %02X, md5_result[i]); // %02X确保大写两位 } // 发送给Qt上位机 esp_at_response_send(MD5:%s, md5_str); // 如MD5:9E107D9D372BB6826BD81D3542A419D6关键参数%02X中的0表示补零2表示宽度X表示大写十六进制。若用%x小写在Qt里用toUpper()转换但嵌入式端资源紧张直接大写更高效。4.3 BLE特征值读写QByteArray与uint8_t*的零拷贝转换BLE通信中特征值Characteristic的数据是uint8_t*而Qt的QBluetoothService要求QByteArray。强行QByteArray::fromRawData()有生命周期风险必须零拷贝。// 正确做法用QByteArray的构造函数接管内存需确保内存持久 uint8_t *ble_data get_ble_buffer(); // 假设指向有效内存 int len get_ble_length(); QByteArray qt_data(reinterpret_castchar*(ble_data), len); qt_data.detach(); // 分离共享内存避免后续BLE释放导致悬空指针 // 发送HEX字符串到QML QString hexDisplay qt_data.toHex( ).toUpper(); emit bleDataReceived(hexDisplay);经验技巧detach()是关键。如果不调用qt_data和ble_data共享同一块内存BLE栈释放缓冲区后qt_data再访问就会崩溃。实测中未调用detach()导致Qt应用在BLE断连后随机崩溃耗时两天定位。5. 工具链协同避坑指南Keil、VS Code、Qt Creator的HEX格式战争不同IDE对HEX的理解南辕北辙协同工作时必须建立统一约定。以下是我在三个主流环境中的实战配置清单。5.1 Keil5.hex文件生成与校验的硬性规则Keil MDK-ARM v5.37生成.hex文件必须在Options for Target → Output选项卡中勾选“Create HEX File”。但默认生成的HEX有两大隐患起始地址偏移Keil默认从0x00000000开始但ESP32的bootloader要求固件从0x10000开始。必须在Options for Target → Target选项卡中设置“IROM1 Start”为0x10000“Size”为0x1F00002MB Flash减去分区表。校验和算法Keil的.hex文件校验和是按Intel HEX规范计算的但某些烧录工具如esptool.py会忽略校验和只认数据。为保险起见禁用Keil的校验和生成在Options for Target → Output → “Hex File”设置中取消勾选“Include Checksum”。Keil设置项推荐值为什么Output → Create HEX File✓必须开启Target → IROM1 Start0x10000匹配ESP32分区表Target → IROM1 Size0x1F0000留足空间给OTAOutput → Hex File → Include Checksum✗esptool.py不校验反而增加解析负担5.2 VS Code OpenOCD.elf转.hex的隐藏开关VS Code配合Cortex-Debug插件和OpenOCD生成.hex文件需在launch.json中配置preLaunchTask。但默认arm-none-eabi-objcopy命令生成的.hex不兼容Keil格式{ version: 2.0.0, tasks: [ { label: elf2hex, type: shell, command: arm-none-eabi-objcopy, args: [ -O, ihex, // 关键指定Intel HEX格式 -R, .stack, // 移除stack段避免地址冲突 ${fileDirname}/${fileBasenameNoExtension}.elf, ${fileDirname}/${fileBasenameNoExtension}.hex ], group: build } ] }核心参数-O ihex强制Intel HEX格式-R .stack移除stack段否则.hex文件会包含未初始化的stack区域烧录后RAM被清零。实测发现未加-R .stack烧录到ESP32后首次运行崩溃因为stack区域被写入了0xFF。5.3 Qt Creator串口助手的HEX显示终极配置Qt Creator自带的Serial Terminal插件HEX显示有三个致命缺陷不支持大写、不支持空格分隔、不支持复制HEX字符串。必须手动修改配置打开Tools → Options → Serial Terminal在“Display”选项卡中勾选“Show hexadecimal values”取消勾选“Show ASCII values”避免双显示干扰设置“Hexadecimal separator”为空格在“Send”选项卡中勾选“Send as hexadecimal”发送HEX字符串时启用设置“Hexadecimal prefix”为0x方便输入隐藏技巧Qt Creator的串口助手不支持复制HEX视图。解决方案是右键点击HEX区域选择“Copy All”然后粘贴到文本编辑器再用正则替换\n为空格得到连续HEX串。或者用QSerialPort自己写个简易终端调用QByteArray::toHex( ).toUpper()。6. 全链路验证案例从Qt发送HEX到ESP32执行并回传校验最后用一个完整案例串联所有知识点Qt上位机发送HEX指令ESP32解析执行回传HEX校验结果。6.1 Qt侧构建可验证的HEX发送器// MainWindow.h private slots: void onSendHexClicked(); private: QSerialPort *m_port; QByteArray m_lastSent; // MainWindow.cpp void MainWindow::onSendHexClicked() { QString hexInput ui-lineEditHex-text().trimmed(); // 预处理移除0x、空格、换行 hexInput hexInput.replace(0x, ).replace( , ).replace(\n, ); if (hexInput.length() % 2 ! 0) { QMessageBox::warning(this, 错误, HEX字符串长度必须为偶数); return; } QByteArray bytes QByteArray::fromHex(hexInput.toLatin1()); if (bytes.isEmpty()) { QMessageBox::warning(this, 错误, HEX格式无效); return; } m_lastSent bytes; // 记录发送内容用于后续校验 m_port-write(bytes); // 显示发送内容HEX格式 ui-textEditLog-append(→ 发送: bytes.toHex( ).toUpper()); }6.2 ESP32侧AT固件扩展指令解析在esp-idf的AT固件中添加自定义指令ATHEXTEST// at_custom_cmd.c #define CMD_TEST_HEX ATHEXTEST #define CMD_TEST_HEX_LEN 10 // 解析HEX字符串为字节数组 static esp_err_t hex_string_to_bytes(const char *hex_str, uint8_t *out_bytes, size_t *out_len) { size_t len strlen(hex_str); if (len % 2 ! 0) return ESP_ERR_INVALID_ARG; *out_len len / 2; for (size_t i 0; i len; i 2) { char hex_pair[3] {hex_str[i], hex_str[i1], \0}; out_bytes[i/2] (uint8_t)strtol(hex_pair, NULL, 16); } return ESP_OK; } // AT指令处理函数 static esp_err_t at_test_hex(uint8_t *cmd, uint8_t cmd_len) { char *hex_param strstr((char*)cmd, ); if (!hex_param) return ESP_ERR_INVALID_ARG; hex_param; // 跳过 uint8_t data[64]; size_t data_len; if (hex_string_to_bytes(hex_param, data, data_len) ! ESP_OK) { at_response_send(ERROR); return ESP_FAIL; } // 执行测试计算CRC32 uint32_t crc esp_crc32_le(0, data, data_len); // 回传HEX字符串先转HEX再拼接 char response[128]; sprintf(response, HEXTEST:%08X, crc); // CRC32为8字符HEX at_response_send(response); return ESP_OK; }6.3 全链路验证步骤Qt上位机输入41542B525354即ATRST的HEX点击发送Qt日志显示→ 发送: 41 54 2B 52 53 54ESP32收到后解析为6字节计算CRC32得0x3A7F2B1EESP32回传HEXTEST:3A7F2B1EQt解析响应提取3A7F2B1E用QByteArray::fromHex()转回4字节验证CRC正确性最终验证用逻辑分析仪抓取UART波形确认发送的确实是0x41 0x54 0x2B 0x52 0x53 0x54六个字节而非4154...八个ASCII字符。这是检验HEX转换是否正确的金标准。我在实际项目中曾因Qt侧未做hexInput.replace( , )导致发送了带空格的HEX字符串ESP32解析出错设备重启循环。后来在Qt侧加了输入校验和波形验证才彻底解决。说到底ASCII与HEX的转换不是写两行代码就完事而是贯穿开发、调试、烧录、验证全链路的底层契约。每一次发送前都该问自己一句我现在操作的是字节还是字符串

相关新闻

pgwatch Kubernetes 部署指南:Helm Chart 安装与云原生环境最佳实践

pgwatch Kubernetes 部署指南:Helm Chart 安装与云原生环境最佳实践

pgwatch Kubernetes 部署指南:Helm Chart 安装与云原生环境最佳实践 【免费下载链接】pgwatch 🔬pgwatch: PostgreSQL metrics monitor/dashboard 项目地址: https://gitcode.com/gh_mirrors/pg/pgwatch pgwatch 是一个专注 PostgreSQL 监控的开…

2026/8/25 9:43:37 阅读更多 →
软件功能测试面试全攻略:100道高频题解析

软件功能测试面试全攻略:100道高频题解析

1. 软件功能测试面试题的价值与定位对于刚毕业的应届生来说,软件功能测试岗位往往是进入IT行业的首选切入点。不同于性能测试、安全测试等需要特定技术积累的领域,功能测试更注重对软件质量保证基础理念的理解和基本测试技能的掌握。这100道面试题的设计…

2026/8/25 9:42:34 阅读更多 →
Java后端开发知识体系与面试实战指南

Java后端开发知识体系与面试实战指南

1. Java 后端开发者知识体系全景图作为一名从业十年的Java后端老兵,我深知面试和日常开发对知识体系的要求差异巨大。面试更像是一场限时开卷考试,需要在短时间内向面试官证明你的技术广度和深度。这份大纲不是简单的知识点罗列,而是经过上百…

2026/8/25 9:42:34 阅读更多 →

最新新闻

AI Agent混合集群路由器的设计与实现:统一调度OpenClaw与Hermes

AI Agent混合集群路由器的设计与实现:统一调度OpenClaw与Hermes

1. 项目缘起:当两个AI Agent“军团”需要协同作战时最近在折腾AI Agent的落地应用,很多团队都面临一个现实问题:手头可能同时运行着不止一套Agent系统。比如,我们团队内部就同时维护着基于OpenClaw和基于Hermes的两套Agent集群。O…

2026/8/25 10:21:50 阅读更多 →
Docker 本地部署 CSR 前端项目完整指南

Docker 本地部署 CSR 前端项目完整指南

文章目录一、前言二、为什么使用 Docker 部署前端项目三、准备工作3.1 安装 Docker Desktop3.2 配置 Docker 镜像加速器(可选但推荐)四、项目结构和配置文件详解4.1 Dockerfile4.2 nginx.conf4.3 docker-compose.yml4.4 .dockerignore五、部署步骤方法一…

2026/8/25 10:21:50 阅读更多 →
基于QClaw与OpenClaw构建智能记账Agent:从Skill开发到AI应用集成实战

基于QClaw与OpenClaw构建智能记账Agent:从Skill开发到AI应用集成实战

1. 项目概述:在QClaw上构建一个会思考的记账机器人最近在折腾鹅厂的OpenClaw生态,特别是它的核心应用QClaw。这东西本质上是一个AI Agent(智能体)的集成与运行平台,你可以把它想象成一个“AI应用商店”或者“AI技能中枢…

2026/8/25 10:21:50 阅读更多 →
Docker 本地部署 SSR 前端项目实战指南

Docker 本地部署 SSR 前端项目实战指南

文章目录1. 项目技术栈2. 项目目录结构3. 核心配置文件详解3.1 Dockerfile (多阶段构建)3.2 docker-compose.yml (编排与网络)3.3 next.config.ts (构建配置)4. 为什么容器内不需要 Nginx?5. 部署步骤这篇文档详细介绍如何将基于 Next.js 的银企直连前置机管理系统(…

2026/8/25 10:21:50 阅读更多 →
Flexsim中AGV锁死问题的根源分析与四大解决策略

Flexsim中AGV锁死问题的根源分析与四大解决策略

1. 项目概述:当AGV在Flexsim中“卡住不动”时如果你刚开始用Flexsim做物流仿真,特别是涉及到AGV(自动导引车)的模型,那么“锁死”或“死锁”这个问题,你大概率很快就会遇到。想象一下这个场景:你…

2026/8/25 10:21:50 阅读更多 →
nginx - 开启 gzip 压缩

nginx - 开启 gzip 压缩

文章目录一、 服务器端开启 Gzip 压缩二、 客户端开启 Gzip 压缩(也需要配置 nginx)三、总结1️. vite-plugin-compression 的作用2️. Nginx Gzip 压缩与插件的区别3️. 实际项目选择建议四、常见问题1️. Nginx 配置作用域规则2. gzip_static on; 的作…

2026/8/25 10:20:42 阅读更多 →

日新闻

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

【题目来源】 https://www.luogu.com.cn/problem/P7912 【题目描述】 小熊的水果店里摆放着一排 n 个水果。每个水果只可能是苹果或桔子,从左到右依次用正整数 1,2,…,n 编号。连续排在一起的同一种水果称为一个“块”。小熊要把这一排水果挑到若干个果篮里&#x…

2026/8/25 0:00:34 阅读更多 →
Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG 【免费下载链接】transformers.js State-of-the-art Machine Learning for the web. Run 🤗 Transformers directly in your browser, with no need for a server! 项目地址: https:/…

2026/8/25 0:00:34 阅读更多 →
数学建模竞赛论文写作指南:从模型构建到学术表达的核心技能

数学建模竞赛论文写作指南:从模型构建到学术表达的核心技能

1. 项目概述:从“会做”到“会写”的竞赛核心跃迁“全国大学生数学建模竞赛”,这个名字对理工科学生来说,分量极重。每年,无数团队在三天三夜的时间里,为一个开放性问题绞尽脑汁,从建立模型、求解算法到编程…

2026/8/25 0:00:34 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/25 3:38:12 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/25 3:38:18 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/25 3:38:23 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/24 20:22:44 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/24 11:20:22 阅读更多 →