仅在特定域的框架内加载时才显示内容?

时间:2014-09-02 11:30:08

标签: php html session iframe referer

关于帧检测的大多数问题似乎来自希望阻止其网站出现在框架内的人们。但是,我试图找到一种方法来拒绝显示特定的php页面,除非它在一个框架中。需要注意的是,iframe和主页面位于不同的域中。

domain1.com/index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Site/title>
        <meta name="viewport" content="width=device-width,minimum-scale=1.0">
        <meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
        <meta HTTP-EQUIV="Expires" CONTENT="-1">
    </head>
    <body>
        <div id="content">
            <iframe width="100%" height="100%" frameborder="0" src="http://domain2.com/browse.php" />   
        </div>
    </body>
</html>

我已尝试以下方法作为验证方式:

  • 查看domain2.com/browse.php中的REFERER信息,看看它是否来自domain1.com/index.php。这取得了有限的成功,因为我每天记录了大约1,000名访客信息被禁用的访客

  • 将用户的IP地址从domain1.com/index.php传递到domain2.com/browse.php,作为加密查询字符串的一部分。这也取得了有限的成功,但我认为缓存(尽管我试图禁用它)导致index.php将旧的加密查询字符串传递给具有过时IP地址的browse.php。

理想情况下,我想知道domain2.com/browse.php是否已在domain1.com/index.php中加载,但如果无法实现,请访问browse.php如果内容不在iframe中,则不显示内容。

非常感谢

2 个答案:

答案 0 :(得分:0)

您已在问题中使用过PHP标记。为什么不使用PHP来包含外部页面:

<?php

// get doc from url
$doc = new DOMDocument;
$doc->loadhtmlfile('http://bitinfocharts.com/x11coin/');

function getElements($tagName,$stripTag = FALSE)
// echo all these elements in direct succession
{
  global $doc;
  $elements = $doc->getElementsByTagName($tagName);
  foreach ($elements as $node)
  {
    $html = $doc->savehtml($node);
    if ($stripTag)
    {
      $html = substr($html,strpos($html,'>')+1);
      $html = substr($html,0,strrpos($html,'<'));
    }
    echo $html;
  }
}

?><!doctype html>
<html lang=en>
    <head>
        <title>Site</title>
        <meta name="viewport" content="width=device-width,minimum-scale=1.0">
        <meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
        <meta HTTP-EQUIV="Expires" CONTENT="-1">
        <?php echo '        <base href="'.$url.'">'.PHP_EOL; ?>
        <?php echo '        '; getElements('link'); ?>
        <?php echo '        '; getElements('script'); ?>
        <?php echo '        '; getElements('style'); ?>
    </head>
    <body>
        <div id="content">
           <?php getElements('body',TRUE); ?>
        </div>
    </body>
</html>

我并不是说这是完美的,我也不知道这是你想要的,但它很好地隐藏了外部资源。密码保护它,没有人可以加载它。

您坚持使用<iframe>。您可以做的是使用一个简单的本地php文件检索外部文件,您猜对了,file_get_contents()并回显它。您需要添加到内容中的所有内容都是<base>标记。这有什么用?两点:

  1. 您现在可以限制从外部服务器下载到您希望允许下载它的服务器。
  2. 该服务器恰好是您的<iframe>页面所在的服务器。在您提供他们刚刚下载<iframe>页面的<iframe>内容之前,您可以检查该服务器。
  3. 因此,您不需要在服务器之间进行任何通信来验证下载。请确保未缓存<iframe>页面!

    (抱歉这么多编辑,但这个编辑器有点奇怪。)

答案 1 :(得分:0)

所以,我的想法是在本地下载外部页面。我们称之为本地页面&#39; LOCAL&#39;。然后让我们在“&#39; IFRAME&#39;”中调用要加载的页面。

您可以限制将外部页面下载到LOCAL所在的服务器。

验证用户是否有权查看LOCAL的最简单方法是使用编码时间戳。因此,当服务器生成IFRAME时,它只是将编码的时间戳放在LOCAL的URL上。为何编码?因为它不应该太明显,你需要能够在LOCAL中解码它。

首先是生成编码时间戳的方法:

$code = urlencode(gzencode(time()));

在LOCAL中,我们将使用相反的方法:

$timestamp = gzdecode(urldecode($code)));

请测试这些例程,urldecode()可能已经在您的服务器上应用了。如果你想让黑客更难以猜测发生了什么,你可以使解码例程的这些编码变得更加复杂。

现在,在您的LOCAL文件中,首先需要检查您获得的时间戳确实是一个数字而不是太旧:

if (is_numeric($timestamp)) $age = abs(time()-$timestamp); 
                       else $age = 99999999;

例如,如果内容超过5分钟,则可以提供空白页面。不要忘记在LOCAL中设置<base>标记,您可以使用DOM类,就像我之前的回答一样。或者,您可以使所有相对链接绝对。

这个想法存在一个明显的缺点。可能有javascripts依赖于它们在外部服务器上运行的事实。在这种情况下,他们不会,这可能会打破他们。

(为什么我会制作这么多拼写错误?)