【问题标题】:Save HTTP_REFERER with mod_rewrite?用 mod_rewrite 保存 HTTP_REFERER?
【发布时间】:2011-04-04 15:53:24
【问题描述】:

实际上我正在尝试在 .htaccess 中传递引用者。我想要做的是将引用值发送到 PHP 脚本,在该脚本中该值将保存到数据库中。在某些情况下(取决于引用者),图像应被阻止(热链接),而在某些其他情况下,图像应正常显示。但它不起作用:-(我当前的“尝试”如下所示(它只是为了测试,所以目前每个图像都会被处理):

RewriteCond %{REQUEST_URI} (.*)jpg$
RewriteCond %{ENV:verified}  ^$  
RewriteRule (.*)jpg$   /include/referrer.php?ref=%{REQUEST_FILENAME}&uri=%{REQUEST_URI}&query=%{QUERY_STRING}&env=%{ENV:verified} [E=verified:yes]

RewriteCond %{REQUEST_URI} (.*)jpg$
RewriteCond %{ENV:verified} ^yes$
RewriteRule ^(.*)$    %{REQUEST_FILENAME} [E=verified:no]

referrer.php 看起来像:

<?
 log_img($_REQUEST['uri'].' - "'.$_REQUEST['env'].'"');
?>

问题是调用了referrer.php但是图片不会显示,很明显是因为没有达到第二条规则。

我也尝试过在referrer.php中显示图片,比如:

<?
 log_img($_REQUEST['uri'].' - "'.$_REQUEST['env'].'"');
 $src = str_replace($_SERVER['DOCUMENT_ROOT'],'',$_REQUEST['ref']);
?>
<img src="<? echo $src ?>" />

但随后再次调用 .htaccess,我将陷入无限循环。

现在的问题是:我怎样才能访问第二条规则,或者我怎样才能实现我想做的事情。有什么办法吗?

感谢您的帮助, 拉尔斯

【问题讨论】:

    标签: .htaccess rewrite mod-rewrite referrer http-referer


    【解决方案1】:

    您当前的解决方案不起作用,因为mod_rewrite 只能用于将请求重写到单个目的地,但您似乎希望请求绕道到您的 PHP 脚本,然后继续处理图像。可能会导致触发 PHP 脚本的子请求,但我认为在这种情况下无法控制原始请求是否继续发送到图像。

    这里最好的做法是让您的 PHP 文件在执行您打算执行的任何检查/记录后打印出实际的图像数据(不是引用图像的图像标签)。您可以使用readfile() 执行此操作,前提是您发送正确的标头。在确保文件是您想要提供的图像之一(而不是系统上的任意文件......)之后,您至少需要determine the appropriate content type,然后打印出数据。考虑缓存(参见this answer,以及this one)也是一个好主意。

    结合上面提到的一些技术,一个简单的引荐来源脚本伪示例如下。请注意,您应该研究实现所描述技术的最佳方法,并且您需要特别注意安全性,因为您要打开文件并打印其内容。

    $filename = /* sanitized file name */;
    
    log_img(/* log some data about the request */);
    
    if (file_exists($filename) && allowedToView($filename)) {
        // Assume we're not on PHP 5.3...
        $types = array(
            'gif' => 'image/gif',
            'png' => 'image/png',
            'jpg' => 'image/jpg',
        );
        $parts = pathinfo($filename);
        $ext   = strtolower($parts['extension']);
    
        if (array_key_exists($ext, $types)) {
            $mime = $types[$ext];
            $size = filesize($filename);
            $expires  = 60 * 60 * 24 * 30;
    
            if (!empty($_SERVER['IF-MODIFIED-SINCE'])) {
                $modified = filemtime($filename);
                $cached   = strtotime($_SERVER['IF-MODIFIED-SINCE']);
    
                if ($modified <= $cached) {
                    header('HTTP/1.1 304 Not Modified');
                    exit();
                }
            } 
    
            header("Content-Type: $mime");
            header("Content-Length: $size");
            header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires)
                . ' GMT');
            header('Cache-control: private, max-age=' . $expires);
            readfile($filename);
            exit();
        }
    }
    
    header("HTTP/1.0 404 Not Found");
    exit();
    

    就 .htaccess 文件而言,它就是这样的(您添加到查询字符串中的内容无论如何都可以在 $_SERVER 中找到,所以我认为手动将其传递给脚本没有任何意义):

    RewriteEngine on
    
    RewriteRule \.(jpg|png|gif)$ /include/referrer.php [NC]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多