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

发布于 2024-10-26 09:01:10 字数 162 浏览 8 评论 0原文

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

  1. 我们如何知道邮件何时被打开?以及图像如何 生成?
  2. IP 地址是如何检测到的以及如何获知位置 它?

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?

  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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小镇女孩 2024-11-02 09:01:10

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

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

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

tracker.php 脚本将位于您的服务器上,并且在调用时,它将:

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

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

$ipAddress = $_SERVER['REMOTE_ADDR'];

并且,从这个 IP 地址开始,您可以使用地理定位服务来找出世界上的哪个地方电子邮件已被打开。

举几个例子,您可以看看MaxMind,或IPInfoDB

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

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

<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=123456 as a parameter.

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

  • Check the id parameter,
  • 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 id different 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.

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

$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

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

冷清清 2024-11-02 09:01:10

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

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

它的工作非常简单,一旦您的邮件打开,该跟踪器图像就会向服务器发送请求,从该请求我们可以通过使用 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.位置:

位置是通过任何地理定位服务获取的,您可以使用开源地理定位查找器,例如 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'];
?>

1. Place the tracker image at the E-mail

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

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

2. On the 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.

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:

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

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'];
?>
无人问我粥可暖 2024-11-02 09:01:10

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

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

AddHandler application/x-httpd-lsphp .png 

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

您可能已经有一个 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'"; 
  }

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

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/.gif etc image file extension.

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

AddHandler application/x-httpd-lsphp .png 

...to allow processing of PHP code within files with a .png extension.

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

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

<?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.

深白境迁sunset 2024-11-02 09:01:10

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

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

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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文