Nginx 通过 location 配合 empty_gif 模块实现像素埋点,利用浏览器自动请求 1×1 透明 GIF 的特性,将用户行为编码于 URL 参数中,由 Nginx 拦截并记录日志后直接返回 43 字节 GIF 响应,无需后端服务。

在 Nginx 中用 location 配合 empty_gif 实现网页像素埋点,本质是利用浏览器对 GIF 图片的自动请求行为,将用户行为(如页面访问、按钮点击)编码进 URL 路径或查询参数中,由 Nginx 拦截并记录日志,不返回真实图片内容,仅返回一个 1×1 透明 GIF 的二进制响应。
原理与前提
需要 Nginx 编译时启用 ngx_http_empty_gif_module(默认已内置,无需额外安装)。该模块提供 empty_gif 指令,可直接返回标准的 1×1 透明 GIF 数据(43 字节),HTTP 状态码为 200,Content-Type 为 image/gif。
埋点触发方式:前端通过 <img src="/log.gif?u=/home&e=click&id=123"> 这类 URL 发起请求,Nginx 匹配到对应 location 后,不代理、不重写、不读文件,直接返回空 GIF 并记录日志。
基础配置示例
以下配置实现最简埋点入口:
- 定义一个专用于埋点的
location /log.gif - 使用
empty_gif指令立即返回透明 GIF - 配合
log_format提取 URL 参数,写入独立日志文件
在 http 块中添加自定义日志格式:
log_format track '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'args: $args u="$arg_u" e="$arg_e" id="$arg_id"'在 server 块中配置 location:
location = /log.gif {
empty_gif;
access_log /var/log/nginx/track.log track;
# 可选:禁止缓存,确保每次请求都打点
expires -1;
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
}增强实用性技巧
-
支持多类型埋点路径:用前缀匹配代替精确匹配,例如
location ^~ /log/,然后前端请求/log/page?u=/product或/log/click?id=abc,再用$uri和$args区分场景 -
校验与过滤无效请求:添加
if ($arg_u = "") { return 444; }拒绝缺少关键参数的请求(注意if在 location 内慎用,仅限简单判断) -
避免日志刷爆磁盘:对埋点 location 单独设置
access_log off,改用log_subrequest on+ Lua 模块做异步落库;或用buffered_logs on减少 I/O -
兼容 referer 或 UA 识别来源:在 log_format 中保留
$http_referer和$http_user_agent,便于后续分析渠道和设备
前端调用注意事项
- 图片 URL 必须带协议或根路径(如
/log.gif?...),避免相对路径导致跨域或 404 - 参数名统一约定(如
u=页面路径、e=事件类型、id=唯一标识),方便后端解析 - 可配合 JS 动态拼接 URL 并创建
new Image().src = url,避免 DOM 插入影响渲染 - 不依赖响应体内容,所以即使 GIF 返回失败(如 Nginx 重启),只要请求发出即算埋点成功(服务端需保障高可用)
这种方式轻量、零依赖、无 JS 执行开销,适合做首屏加载、静态页曝光、邮件链接追踪等场景。真正要分析数据时,从 track.log 中提取结构化字段,导入 ELK 或用 Logstash 清洗即可。


















