使用 PHP 和图像跟踪电子邮件

Posted

技术标签:

【中文标题】使用 PHP 和图像跟踪电子邮件【英文标题】:Tracking email with PHP and image 【发布时间】:2011-07-23 19:59:11 【问题描述】:

我已经看到像 spypig.com 这样的服务在电子邮件中放置一个小图像并跟踪它何时打开以及从何处打开。他们跟踪城市、国家、IP 地址等。这是如何完成的?

    我们如何知道邮件何时打开?以及图像如何 生成? 如何检测到 IP 地址以及如何知道位置 是吗?

【问题讨论】:

你想用这个做什么?许多电子邮件客户端无论如何都会检查此网络错误并且不会显示它们,因此您不能在严肃的应用程序中依赖它。 我强烈建议您添加一个实际的图像扩展名 (.jpg,.png) 并返回实际的图像标题。例如... /o/uuid-email-identifier/good.jpg - 使其动态化。这就是我在我的软件中所做的事情 【参考方案1】:

基本上,在您的电子邮件的 html 正文中,会有一个如下所示的 <img> 标记:

<img src="http://www.yoursite.com/tracker.php?id=123456"  />

当有人阅读他的邮件并启用图像时,电子邮件客户端将向tracker.php 发送请求以加载图像,并将id=123456 作为参数传递。

这个tracker.php 脚​​本将在您的服务器上,并且当被调用时,它将:

检查id参数, 使用它来查找它对应的电子邮件地址 - 在为每个订阅者生成电子邮件时,您将为每封电子邮件生成不同的 id。 做一些事情——比如记录“电子邮件 123456 已打开”,以及一些其他信息 返回小图的内容;就像一个 1x1 透明 gif。

tracker.php 脚本知道它是从哪个 IP 地址调用的——就像任何其他 PHP 脚本一样:

$ipAddress = $_SERVER['REMOTE_ADDR'];

而且,从这个 IP 地址开始,您可以使用地理定位服务来找出电子邮件是从世界上的哪个地方打开的。 举几个例子,你可以看看MaxMind,或者IPInfoDB

如您所知,id=123456 对应一个特定的电子邮件地址,这可以让您了解每个订阅者的位置。

【讨论】:

我想您可以跳过返回图像,但显示损坏的图像图标会很难看。而且我不建议您在电子邮件中使用 display:none,因为现在垃圾邮件过滤器非常严格,使用它可能会使您的电子邮件直接进入垃圾邮件文件夹甚至可能拒绝它,因为过滤器会认为您是隐藏恶意文本或代码。即使在白色背景上使用白色文本也可能触发此操作 如何从tracker.php返回image 为什么不在电子邮件内容中使用另一张图片,即实际需要渲染的图片,即徽标、标题图片等? 另外,如果有人离线阅读邮件,此方法将不起作用。我说的对吗? $ipAddress = $_SERVER['REMOTE_ADDR']; 不返回正确的ip地址,它返回一个属于google的66.249.84.194 ip地址,任何人都可以帮我解决这个问题。【参考方案2】:

1.将跟踪器图像放在电子邮件中

<img src="http://www.yoursite.com/tracker.php?eid=123456&uid=123"   >

它的工作很简单,一旦你的邮件被打开,那个tracker image就会向服务器发送请求,从这个请求中我们可以通过创建带有userID的图像URL来获取信息,并且还认为邮件被用户。

注意:不要使用 display: none;隐藏图像的属性,它可能会被垃圾邮件算法过滤。并且不要放置任何javascript代码,它也会阻止垃圾邮件过滤器

2。在 tracker.php 上

<?php
header("Content-Type: image/jpeg"); // it will return image 
readfile("img.jpg");

dbfunction(); // place your db code
?>

3. ip地址通过以下函数获取。

function get_client_ip() 
    $ipaddress = '';
    if (isset($_SERVER['HTTP_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_X_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    else if(isset($_SERVER['REMOTE_ADDR']))
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;

$PublicIP = get_client_ip();

4.地点:

位置是通过任何地理定位服务获取的,您可以使用开源的 GeoLocation finder,例如 nekudo,freegeoip。

例如

<?php
$json  = file_get_contents("http://ipinfo.io/$PublicIP/geo");
$json  =  json_decode($json ,true);
$country =  $json['country_name'];
$region= $json['region_name'];
$city = $json['city'];
?>

【讨论】:

也许我错了,但是必须在服务器上调用 ipecho-part,所以您只能获取服务器的 IP 地址?【参考方案3】:

其他答案很好,但是,由于人类似乎确信“任何跟踪都是邪恶的跟踪”,我希望通过保留 .png/@987654324 对用户“不可见”更进一步@/.gif等图片文件扩展名。

我不确定与所有类型的 Web 服务器和主机的兼容性,但对我来说,这是对我在 .htaccess 中已有的 AddHandler 指令的快速更改,例如:

AddHandler application/x-httpd-lsphp .png 

...允许处理带有.png 扩展名的文件中的 PHP 代码。

您可能已经有一个AddHandler 行来允许在.htm/.html 文件中使用PHP;如果是这样,只需将适当的图像文件扩展名添加到列表末尾即可。

这大致是我的“跟踪图像”代码、保存为trackimage.png 或其他格式的文件:

<?php //silently log user and return image
  $ip=$_SERVER['REMOTE_ADDR'];
  $uri=tidy($_SERVER['SCRIPT_URI']);
  $querystring=tidy($_SERVER['QUERY_STRING']);
  $useragent=tidy($_SERVER['HTTP_USER_AGENT']);

  $json  = file_get_contents("https://ipinfo.io/".$ip."/geo");
  if(($json<>'')&&(strpos($json,"error")===false)) extract(json_decode($json ,true)); 
  $country=tidy($country);
  $prov=tidy($region);
  $city=tidy($city);
  list($lat,$lon)=explode(',',$loc);
  $lat=tidy($lat);
  $lon=tidy($lon);

  $sql = "INSERT INTO img_track_table set ip='$ip', useragent=$useragent, uri=$uri, " 
    ."querystring=$querystring, country=$country, prov=$prov, city=$city, lat=$lat, lon=$lon;";

  require 'connect.php'; $conn=new mysqli($servername, $username, $password, $dbname);
  if ($conn->connect_error)  /* couldn't connect, but do nothing about it */  
  else  //run insert query
    if(!$conn->query($sql))  /* query error, but do nothing about it */ 
    $conn->close();
  

  //return image
  header("Content-Type: image/png"); 
  readfile("myActualImageFile.png");

  function tidy($str) //remove quotes and backslashes from string
    if(is_null($str)||($str==""))return "null";
    $str=trim(str_replace('\\','',str_replace("'","",str_replace('"',"",$str))));
    if(is_numeric($str))return $str;
    return "'$str'"; 
  

请注意,如果图像之前的代码返回错误文本或其他任何内容,则图像将无法显示。可能还值得研究可能适用于您的情况的可能的安全问题。例如,this。

【讨论】:

谢谢,非常有用。 AddHandler 没有为我完成这项工作,但 AddType application/x-httpd-php .php .png【参考方案4】:

关于问题的第一部分,我所做的是从 PHP 文件返回图像。除了返回图像(可以是 1x1 像素透明 png)之外,还将所有信息记录到数据库中。这样,当调用 PHP 文件时,您就知道图像已加载,即电子邮件已被读取。问题是许多现代客户端不会自动加载图像。出于隐私原因,这是不允许您尝试做的事情。

关于第二部分,有几个地理位置 Web 服务,您可以在其中提交 IP 并获取地理位置。您可以在返回 1x1 像素图像的 PHP 文件中执行此操作。 这是本网站上关于此的一个很好的主题: Geolocation web service recommendations

【讨论】:

以上是关于使用 PHP 和图像跟踪电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

电子邮件跟踪图像记录

跟踪图像文件的链接或引用并删除未使用的文件(PHP/数据库)

跟踪大量电子邮件活动

群发邮件追踪

电子邮件跟踪 - GMail

图像工程——目标检测与目标跟踪