我有一台用于发送电子邮件的服务器。电子邮件中有一张用于跟踪其打开情况的图片,其形式为
<img src="http://tracker.site.com/[email protected]&c=somemd5ishcode">
提供图像的脚本如下:
<?php
// turn off errors
ini_set('display_errors', 0);
ini_set('log_errors', 0);
// database settings
define('DB_HOST','localhost');
define('DB_USER','user');
define('DB_PASSWORD','pass');
define('DB_NAME','db');
// connecting to the db
$dbh = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD,true);
mysql_select_db(DB_NAME, $dbh);
// clean the vars
$code = mysql_real_escape_string( $_GET['c'] );
$email = mysql_real_escape_string( $_GET['e'] );
// insert a record if need be
if( $code <> '' && $email <> '' )
{
// quick debug
$dump = '';
foreach( $_SERVER as $k=>$v )
{
$dump.= '"'. $k .'" => "'. $v .'",\n';
}
mysql_query( "INSERT INTO `tracker_hits`
(`CODE_TEXT`,`HIT_EMAIL`,`HIT_IP`,`HIT_TIMESTAMP`,`SERVER_DUMP`)
VALUES
('$code','$email','{$_SERVER['REMOTE_ADDR']}','" .time(). "','$dump')", $dbh );
}
// disables caching of the image
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
header('Cache-Control: no-cache');
header('Pragma: no-cache');
// outputs a 1x1 transparent PNG
header('Content-type: image/png');
echo gzinflate(base64_decode('6wzwc+flkuJiYGDg9fRwCQLSjCDMwQQkJ5QH3wNSbCVBfsEMYJC3jH0ikOLxdHEMqZiTnJCQAOSxMDB+E7cIBcl7uvq5rHNKaAIA'));
die();
但是,当我发送电子邮件时,我会在同一秒内收到数百次点击,这些点击来自完全相同的 IP 地址,该 IP 地址各不相同,但 whois 显示它属于 Mediacom / Verizon / Frontier / 等。我四处查看,似乎我的问题可能出在 ISP 缓存服务器上。我使用了这个网站:http://redbot.org/检查我的文件的“可缓存性”,他们是这样说的:
HTTP/1.1 200 OK
Date: Thu, 17 Mar 2011 17:05:20 GMT
Server: Apache/2.2.10 (Win32) mod_ssl/2.2.10 OpenSSL/0.9.8i PHP/5.2.6
X-Powered-By: PHP/5.2.6
Expires: Sat, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 87
Keep-Alive: timeout=5, max=500
Connection: Keep-Alive
Content-Type: image/png
附注如下:
General
- The Content-Length header is correct.
Caching
- Pragma: no-cache is a request directive, not a response directive.
- This response allows all caches to store it.
- This response cannot be served from cache without validation.
因此,我四处寻找,发现我可以使用 Apache 的 expires_module 来完成这项工作,但是当使用以下设置进行设置时,我仍然从 REDbot 获得相同的结果:
LoadModule expires_module modules/mod_expires.so
<IfModule expires_module>
ExpiresActive On
ExpiresByType text/php A0
ExpiresByType image/png A0
ExpiresByType image/jpg A0
ExpiresByType image/gif A0
</IfModule>
我遗漏了什么?我环顾四周,据我了解,PHPheader()
和<meta>
标头仅用于用户浏览器,而不是 ISP 缓存。我有一个想法,因为群组 IP 命中都在电子邮件发出后的几秒钟内,所以我可以在我的日志脚本中检查是否至少过了 10 秒才允许命中有效。不过,我认为我可能会遇到的问题是,稍后当有人实际阅读电子邮件时,ISP 是否会捕获该请求并短路将命中记录到我的服务器的请求,然后只向他们提供缓存版本?
答案1
根据 ISP 使用的缓存,您可能没有机会强制执行正确的请求而不是缓存。即使您指定了 mod_expires 和 nocache 等内容,ISP 仍然可以缓存,特别是如果他们运行任何类型的代理。
因此:
1. 即使您在收到邮件后等待 10 秒,也不能保证正确的客户端视图不会被缓存(即,您会看到原始被阻止的 ISP 视图,但之后就什么都看不到了)
2. 您应该寻找更好的方法,即电子邮件收据。3
. 如果您想更新您想要实现的目标,并且如果存在限制,我们可能会帮助您解决更大的问题。