必须先确认 mod_deflate 模块已加载,否则所有压缩配置均无效;需取消 httpd.conf 中 LoadModule deflate_module modules/mod_deflate.so 的注释,并建议同时启用 mod_filter.so 和 mod_headers.so。

确认 Apache 的 mod_deflate 模块已启用
没开这个模块,后面所有配置都无效。打开 C:\xampp\apache\conf\httpd.conf(macOS/Linux 对应路径为 /Applications/XAMPP/xamppfiles/etc/httpd.conf 或 /opt/lampp/apache2/conf/httpd.conf),搜索 mod_deflate.so,找到这行:
#LoadModule deflate_module modules/mod_deflate.so
删掉开头的 #,保存。如果后续压缩仍不生效,再检查是否漏了依赖模块:mod_filter.so 和 mod_headers.so —— 它们虽非压缩必需,但某些压缩策略(如设置 Vary: Accept-Encoding)会用到,建议一并启用:
LoadModule filter_module modules/mod_filter.so<br>LoadModule headers_module modules/mod_headers.so
在主配置中写 Gzip 规则,别依赖 .htaccess
XAMPP 默认把 AllowOverride 设为 None,意味着 .htaccess 里的 AddOutputFilterByType 根本不会执行。必须把规则写进 httpd.conf 文件末尾(或 extra/httpd-vhosts.conf 中对应 <virtualhost></virtualhost> 内):
<IfModule mod_deflate.c><br> AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/javascript application/json application/xml<br> <IfModule mod_headers.c><br> Header append Vary Accept-Encoding<br> </IfModule><br></IfModule>
-
AddOutputFilterByType在 Apache 2.4.x(XAMPP 当前主流版本)中仍可用,但已被标记为过时;若你升级到 Apache 2.5+,得改用AddOutputFilter DEFLATE+AddType显式声明 MIME 类型 - 别加
application/x-httpd-php—— PHP 输出若已启用zlib.output_compression(见php.ini),会导致双重压缩或头冲突,Apache 会跳过压缩 -
Header append Vary Accept-Encoding是关键,否则 CDN 或代理可能缓存错版本
配置多端口时,Gzip 规则要放在全局或每个 <VirtualHost> 内
如果你通过修改 Listen 和新增 <VirtualHost *:8080> 等方式启用了多端口,注意:<IfModule mod_deflate.c> 块默认只作用于主服务器上下文。若某个端口站点没生效,大概率是规则没覆盖到它。
XAMPP 8.0.30 是一款免费、开源的跨平台 Web 服务器集成包,专为快速搭建本地 PHP 开发环境而设计。该版本核心组件包括:Apache 2.4.56、MySQL 8.0.33、PHP 8.0.30、phpMyAdmin 5.2.1 等。它支持 Windows、Linux 和 macOS 系统,可让开发者在个人电脑上轻松模拟服务器环境,无需复杂配置即可运行 WordPress、Thin
- 最稳妥做法:把整个
<IfModule mod_deflate.c>块复制一份,粘贴进每个<VirtualHost>段内部 - 或者——更推荐——把它放在
httpd.conf文件靠后、但仍在所有<VirtualHost>之前的位置,确保被继承(Apache 2.4 默认支持模块指令继承) - 避免在
httpd.conf里用<Location />包裹压缩指令,它和<VirtualHost>作用域容易冲突,且对 PHP 脚本路径处理不稳定
验证压缩是否真起效,别信“看起来快了”
打开浏览器开发者工具 → Network 面板 → 刷新页面 → 点一个 JS 或 CSS 请求 → 查看 Response Headers。只有同时满足以下两点才算成功:
- 存在
Content-Encoding: gzip - 响应体大小(Size 列)明显小于 Transfer Size(即解压后体积)
常见假阳性场景:
- 看到
Content-Encoding: gzip,但 Size 和 Transfer Size 几乎一样 → 实际没压缩,只是 header 被硬塞进去(比如 PHP 代码里写了header('Content-Encoding: gzip')) - 本地开发时用
file://协议打开 HTML → 浏览器根本不发Accept-Encoding请求头,Apache 不会触发压缩 - PHP 脚本开头用了
ob_start('ob_gzhandler')→ 它会抢在 Apache 前压缩并设置 header,导致 Apache 的mod_deflate自动弃权
真正复杂的地方在于:Gzip 行为受 Apache 版本、PHP 输出缓冲、反向代理、甚至浏览器 User-Agent 影响。调通之后,建议用 curl -H "Accept-Encoding: gzip" -I http://localhost:8080/test.js 直接测响应头,绕过浏览器干扰。

















