【问题标题】:.htaccess url-rewrite if file not exists - how to deal with favicon.ico?.htaccess url-rewrite 如果文件不存在 - 如何处理 favicon.ico?
【发布时间】:2017-07-23 16:48:00
【问题描述】:

我正在构建自己的 URL 缩短网站,并将其用作我的 .htaccess 文件:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /go.php [L]
</IfModule>

这应该将任何 URL(不是文件)重定向到 go.php,用于 URL 重定向。

问题是:

当我转到example.com/keyword 时,我会看到go.php 页面。然后,我提取关键字:

$url = $_SERVER['REQUEST_URI'];
$keyword = strtok($url, '?');
$keyword = ltrim($keyword,"/");

然后我将当前关键字及其引用者 ($_SERVER['HTTP_REFERER]) 插入到数据库中的 log 表中。

一切似乎都运行良好,但在我的日志表中有两个新行而不是一个:一个具有正确的关键字 example,另一个具有关键字 favicon.icohttp://example.com/keyword 作为引荐来源。

这里到底发生了什么?我只需要第一行和正确的行。这个问题只发生在favicon.ico 上吗?我该如何解决这个问题?

谢谢!

【问题讨论】:

    标签: php .htaccess redirect mod-rewrite mysqli


    【解决方案1】:

    您的浏览器在请求之后请求favicon.ico-文件。如果它存在,它将使用它作为浏览器选项卡中的图标(例如那个整洁的小 stackoverflow-icon)。

    由于您的服务器上不存在该请求,因此该请求将通过所有重写条件。简单地添加一个额外的条件来忽略(不转发到 go.php)favicon-request。

    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/favicon.ico$
    RewriteRule ^.*$ /go.php [L]
    

    概念证明:http://htaccess.mwl.be?share=f2fa97da-14b9-5c2e-8c58-c2c620b35c76

    额外提示,忽略所有.ico.jpg.css 等(我最喜欢的重写规则):

     RewriteRule !\.(js|ico|gif|jpg|png|css|txt)$ /go.php [L]
    

    【讨论】:

    • 嗨 - 我可以看到你对 htaccess 的了解比我更好:)。我正在做与 OP 类似的操作,但研究了 WordPress 是如何做到的。他们有一个非常强大的重写引擎,您可以在其中拥有漂亮的永久链接(基本上像/thing/another-thing 这样的网址而不是?param=value&amp;another=value。他们的htaccess 不包括favicon 的任何特殊情况,否则。只有这个pastebin.com/1SWBy81X 存在。所以我想知道为什么“世界”需要添加每个异常(favicon 等),而他们不需要 - 必须我们错过了什么?
    【解决方案2】:

    favicon.ico 请求是 example.com/keyword 之外的另一个请求。它由浏览器自动请求,浏览器可以控制favicon.ico 请求的方式。例如,请求的referer 标头可能是触发favicon.ico 的主请求URL,就像你发生的那样,或者它可能是空的。这就是favicon.ico 请求在我的数据库中记录的方式。请注意 Firefox 是如何请求带有空 referer 标头的文件

    如何在服务器端处理该请求

    这里有几个选项

    1-您可以按照@Peter van der Wal 在他的回答中所说的那样从重写规则中排除该文件。

    2- 你可以用 PHP 自己提供文件(我不会这样做),例如你可以这样做

    <?php
    $iconFile ="some-media-directory/cool-icon.php";
    $fileSize = filesize($iconFile);
    $fHandle = fopen($iconFile,"rb");
    header("Content-Type: image/ico");
    $lastModified = gmdate('D, d M Y H:i:s ', filemtime($logoFile)) . 'GMT';
    header("Last-Modified: $lastModified");
    header("Content-Disposition: inline");
    header("Content-Length: $fileSize");
    die(fread($fHandle,$fileSize));
    

    如果您要在 PHP 中自己提供文件,那么您必须管理 Cashe 标头。请看这个问题(Handling If-modified-since header in a PHP-script

    【讨论】:

      猜你喜欢
      • 2011-07-25
      • 2014-04-26
      • 2018-03-20
      • 2012-03-14
      • 2012-11-06
      • 2013-09-19
      • 1970-01-01
      • 2011-07-31
      • 1970-01-01
      相关资源
      最近更新 更多