mod_setenvif的核心作用是根据请求特征(如User-Agent、Remote_Addr、Request_URI等)动态设置环境变量,仅作“打标签”用途,不修改响应或重写URL;支持的attribute包括请求头、IP、URI等,需注意正则匹配规则、大小写敏感及空格陷阱。

mod_setenvif 的核心作用,就是在请求刚抵达 Apache 时,根据请求本身的“指纹”(比如浏览器类型、来源地址、请求路径、Referer、语言偏好等)打上轻量级标签——这些标签是环境变量,不改变响应内容,但能被日志、访问控制、缓存策略甚至后端脚本识别和使用。
哪些请求特征可作为“指纹”来匹配
SetEnvIf 支持的 attribute 类型有限但实用,常见可用字段包括:
- User-Agent:识别爬虫(Baiduspider)、移动端(iPhone|Android)、旧浏览器(MSIE 6)
-
Remote_Addr:匹配内网 IP(
^10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)或特定出口段 -
Request_URI:区分静态资源(
\.js$|\.css$|\.png$)、管理后台(^/wp-admin/|^/api/v1/private) -
Referer:拦截盗链(
^https?://(?!yourdomain\.com).*)或标记来源渠道(含utm_source=weibo) -
Accept-Language:按语言设区域变量(
^zh.*$→lang_zh=1) -
Host:多域名共用配置时区分租户(
^app1\.example\.com$→tenant=app1)
写法要点:正则、大小写与空格陷阱
匹配逻辑看似简单,但极易因细节失效。关键注意事项:
- 默认区分大小写:User-Agent 中 “mobile” 不匹配 “Mobile”,加
i标志更稳妥,如User-Agent "iphone"i - 引号内前后不能有空格:
SetEnvIf User-Agent " Googlebot " is_bot会失败;应写作"Googlebot" - 正则无需强制锚定:
SetEnvIf User-Agent "curl"可匹配curl/8.4.0,子串匹配即生效 - 若需完整匹配(如国家码),用
^CN$;避免CN匹配到CN123或ACN - 反斜杠要加倍:匹配
192.168.0.1写成192\.168\.0\.1,Apache 解析时会吃掉一层
典型实战配置示例
以下配置片段可直接放入 或启用 AllowOverride FileInfo 的 .htaccess 中(注意:.htaccess 仅能继承已定义变量,不能新建):
# 标记主流爬虫,用于日志隔离或限流
SetEnvIf User-Agent "Baiduspider|YisouSpider|360Spider|Bytespider" is_bot=1
<h1>标记中文语言用户(兼容 zh-CN / zh-TW / zh-Hans)</h1><p>SetEnvIf Accept-Language "^zh" lang_zh=1</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill3961" title="Apache Superset Dashboard and SQL Exploration Skill"><img
src="https://img.php.cn/upload/skill/000/000/081/178987691575372.jpg" alt="Apache Superset Dashboard and SQL Exploration Skill" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill3961" title="Apache Superset Dashboard and SQL Exploration Skill" class="overflowclass">Apache Superset Dashboard and SQL Exploration Skill</a>
<p class="overflowclass">Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。</p>
</div>
<a rel="nofollow" href="/xiazai/skill3961" title="Apache Superset Dashboard and SQL Exploration Skill" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><h1>标记来自微信内置浏览器(UA 含 MicroMessenger)</h1><p>SetEnvIf User-Agent "MicroMessenger" in_wechat=1</p><h1>标记内网请求,用于跳过 CDN 缓存</h1><p>SetEnvIf Remote_Addr "^10.|^192.168.|^172.(1[6-9]|2[0-9]|3[0-1])." internal_request=1</p><h1>标记盗链图片请求(Referer 非本站且请求为图片)</h1><p>SetEnvIf Referer "^https?://(?!example.com).*" bad_referer=1
SetEnvIf Request_URI ".(jpg|jpeg|png|gif)$" image_request=1
SetEnvIfExpr "%{env:bad_referer} == '1' && %{env:image_request} == '1'" block_hotlink=1
</p>
设完变量后怎么真正用起来
环境变量只是“标签”,必须配合其他模块才能起效:
-
日志分流:在
LogFormat中用%{is_bot}e,再通过CustomLog ... env=!is_bot排除爬虫日志 -
访问控制:用
Require env=is_bot拒绝爬虫,或Require not env=block_hotlink阻断盗链 -
响应头注入:配合
mod_headers,Header set X-Region "CN" env=lang_zh -
PHP 中读取:用
getenv('is_bot')或$_SERVER['is_bot'](确保variables_order含 E 或 S) -
缓存策略:在
中用CacheIgnoreHeaders Set-Cookie+CacheIgnoreCacheControl env=internal_request









