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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5448381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 21:27:45  来源:igfitidea点击:

Tracking email with PHP and image

phpemailgeolocationtrackingspy

提问by esafwan

I have seen the service like spypig.com placing a small image in the email and tracking when it is opened and from where. They track city, country, IP address etc. How is this done?

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

  1. How do we know when the mail is opened? And how is the image generated?
  2. How is the IP address detected and how is it possible to know location from it?
  1. 我们如何知道邮件何时被打开?以及如何生成图像?
  2. 如何检测 IP 地址以及如何从中知道位置?

回答by Pascal MARTIN

Basically, in the HTML body of your email, there will be an <img>tag that would look like this :

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

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

When someone reads his mail, with images enabled, the email-client will send a request to tracker.php, to load the image, passing it id=123456as a parameter.

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


This tracker.phpscript will be on your server, and, when called, it will :


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

  • Check the idparameter,
  • Use it to find to which email address it corresponds -- when generating the email for each one of your subscribers, you'll have generated an iddifferent for each e-mail.
  • Do some stuff -- like log "email 123456 has been opened", and some additional informations
  • return the content of a small image ; like a 1x1 transparent gif.
  • 检查id参数,
  • 使用它来查找它对应的电子邮件地址——为每个订阅者生成电子邮件时,您将为id每封电子邮件生成不同的电子邮件。
  • 做一些事情——比如记录“email 123456 has been opening”,以及一些额外的信息
  • 返回一个小图像的内容;就像一个 1x1 的透明 gif。


The tracker.phpscript knows from which IP address it's been called -- like any other PHP script :


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

$ipAddress = $_SERVER['REMOTE_ADDR'];

And, starting from this IP address, you can use a geolocation service to find out from where in the world the email has been opened.
As a couple of examples, you could take a look at MaxMind, or IPInfoDB

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

As you know that id=123456corresponds to one specific email address, this allows to find out where each one of your subscribers are.

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

回答by NaveenDA

1. Place the tracker image at the E-mail

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

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

Its working is very simple, Once your mail is open, that tracker image sends the request to the server, from that request we can get information by creating the image URL with userID, and also consider as that mail is read by the user.

它的工作非常简单,一旦您的邮件打开,该跟踪器图像将请求发送到服务器,我们可以从该请求中通过创建带有 userID 的图像 URL 来获取信息,并认为该邮件已被用户读取。

Note: Don't use display: none; property for hiding your images, it may filter by spam algorithm. And don't place any javascript codes, it also blocks the spam filter

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

2. On the tracker.php

2.在tracker.php上

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

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

3. The ip address is get by the following function.

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. Location:

4. 地点:

The location is getting by any geolocation services, you can use open-source GeoLocation finder like nekudo,freegeoip.

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

for example

例如

<?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'];
?>

回答by ashleedawg

The other answers are great but, since humanity seems convinced that "any tracking is evil tracking" I like to take it a step further by being "invisible" to the user by retaining the .png/.jpg/.gifetc image file extension.

其他答案很好,但是,由于人类似乎相信“任何跟踪都是邪恶的跟踪”,因此我喜欢通过保留.png/ .jpg/.gifetc 图像文件扩展名对用户“不可见”来更进一步。

I'm not sure about compatibility with all types of web servers and hosts, but for me it was a quick change to the AddHandlerdirective I already had in .htaccess, such as:

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

AddHandler application/x-httpd-lsphp .png 

...to allow processing of PHP code within files with a .pngextension.

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

You might already have an AddHandlerline to allow PHP in .htm/.htmlfiles; if so, just add the appropriate image file extension to the end of the list.

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

This is, roughly, my "tracking image" code, file saved as trackimage.pngor whatever :

粗略地说,这是我的“跟踪图像”代码、另存为的文件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'"; 
  }

Note that if error text, or anything else, is returned by the code before the image, the image will be undisplayable. It might also be worth researching possible security concerns with this that might apply to you case. For example, this.

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

回答by Elad Lachmi

About the first part of the question, what I did was return the image from a PHP file. Aside from returning an image (it can be 1x1 pixel transparent png) is logging all the info into the database. This way, when the PHP file is called, you know that the image was loaded i.e. the email was read. The problem is that a lot of modern clients don't load images automatically. This is to not allow just the kind of thing you're trying to do, for privacy reasons.

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

About the second part, there are several geolocation web services, where you submit an IP and get the geolocation. You can do that in the PHP file that returns the 1x1 pixel image. Here is a good thread about this on this site: Geolocation web service recommendations

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