<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml xml:lang="zh">
<head>
<meta http-equiv="Content-Type" content="text/vnd.wap.wml; charset=utf-8"/>
<meta http-equiv="Cache-Control" content="no-cache"/></head>
<card title="突破基于 HTTP_REFERER 的防盗链措施 - Gracecode.com">
<p>比较郁闷就是某些“小气”的网站，会加上防盗链的功能（特别本人在看 <a href="http://www.google.com/reader/" title="http://www.google.com/reader/">Google Reader</a> 时）。其实防盗链这个技术并不复杂，目前基本就是在服务器端判断 HTTP_REFERER 的位置，如果不是来自本站自身，则拒绝输出（<a href="http://www.williamlong.info/archives/266.html" title="http://www.williamlong.info/archives/266.html">详细</a>）。</p>

<p>那么如果考虑突破防盗链的措施，就需要考虑在 HTTP_REFERER 上面做手脚了。PHP 脚本中对应的变量是 $_SERVER['HTTP_REFERER'] ，它存储了 HTTP_REFERER 的值。</p>

<p>由于直接访问目标 URL 资源已经被上述防盗链的措施给屏蔽，所以我们需要个类似网关的玩意去获取。说白了就是编写已经包装过的 HTTP 头的 PHP 脚本。</p>

<p>下面是简单的函数实现：</p>

<pre>function getRemoteFile($url, $refer = '') {
    $option = array(
            'http' =&gt; array(
                'header' =&gt; &quot;Referer:$refer&quot;)
            );
    $context = stream_context_create($option);
    return file_get_contents($url, false, $context);
}</pre><p>这是个比较简单的函数，其功能就是伪造 Referer （使用 <a href="http://cn2.php.net/stream_context_create" title="http://cn2.php.net/stream_context_create">stream_context_create 函数</a>）然后获取对方的数据（使用 file_get_contents，需要开启 <a href="http://cn.php.net/manual/en/features.remote-files.php" title="http://cn.php.net/manual/en/features.remote-files.php">allow_url_fopen</a> ）。</p>

<p>如果想“复杂”一点，可以使用 <a href="http://cn2.php.net/manual/en/book.sockets.php" title="http://cn2.php.net/manual/en/book.sockets.php">sockets 扩展</a>，这不在这里的讨论范围以内。</p>

<p>另外，再提供个获取主机名的正则函数</p>

<pre>function getHost($url) {
    $result = preg_match('/^http:\/\/([\d|\w|\.]+)\//', $url, $matches);
    if (sizeof($matches) &gt;= 2)  {
        return $matches[1];
    } else {
        return null;
    }
}</pre><p>再进一步的扩展，可以封装成脚本，然后譬如调用</p>

<pre>http://127.0.0.1/proxy.php?url=http://i.am/img</pre><p>就可以获取那些开启防盗链措施的链接了（再发挥下，使用 Javascript 将图片链接全部替换）。</p>


<p>
<a href="http://www.gracecode.com/wap/">Gracecode.com</a> |
<a href="http://www.gracecode.com/wap/d/1930 ">Permalink</a>(<a href="http://www.gracecode.com/Archive/Display/1930 ">xHTML</a>) |
<a href="http://www.gracecode.com/Trackback/Recieve/1930/1fn3gz">Trackback</a> |
<a href="http://rss.gracecode.com">Rss</a>
</p>
</card>
</wml>