【问题标题】:Is there a way to tell curl to not use cache有没有办法告诉 curl 不使用缓存
【发布时间】:2013-03-07 18:57:10
【问题描述】:

我正在尝试找出 url 的文件大小:

$url1 = 'www.google.com';
$curl1 = curl_init();
curl_setopt($curl1, CURLOPT_URL, $url1); 
curl_setopt($curl1, CURLOPT_RETURNTRANSFER, TRUE);
curl_exec($curl1);
$file_size = curl_getinfo($curl1, CURLINFO_SIZE_DOWNLOAD ); 
$file_size_kb = $file_size / 1000;
echo $file_size_kb;

输出为43331。我认为它太低了,因为我有谷歌缓存。这是真的吗?我还在其他一些计算 url 大小的网站上测试了 google,它的大小是原来的两倍。

【问题讨论】:

    标签: php curl


    【解决方案1】:

    您可以为此使用CURLOPT_FRESH_CONNECT。来自curl_setopt

    CURLOPT_FRESH_CONNECT TRUE 以强制使用新连接而不是缓存连接。

    curl_setopt($curl1, CURLOPT_FRESH_CONNECT, TRUE);
    

    根据RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching5.2. Cache-Control

    “Cache-Control”标头字段用于指定指令 沿着请求/响应链缓存。

    5.2.1. Request Cache-Control Directives 定义了几个指令来控制响应缓存的使用。其中之一是

    5.2.1.4。无缓存

    “no-cache”请求指令表明缓存不能使用 一个存储的响应来满足请求而不成功 在源服务器上进行验证。

    所以设置一个合适的标题

    curl_setopt($curl1, CURLOPT_HTTPHEADER, array("Cache-Control: no-cache"));
    

    应确保返回有效且最新的响应。我了解,如果服务器上的验证允许这样做,这仍可能导致缓存响应。


    但是,5.2.2.1. must-revalidate 是服务器给出的Response Cache-Control Directive 以及对请求的响应

    [...] 当且仅当服务器应该使用 must-revalidate 指令 如果未能验证对表示的请求可能会导致 在不正确的操作中,例如默默未执行的财务 交易。

    【讨论】:

    • 不 - 这不足以拒绝缓存命中。您请求信息的服务器可能仍会回复Cache-Control: public, s-maxage=600(或类似的),无论与服务器的连接是新的还是重复使用的。
    • 不——这只会创建一个新的连接(这只是一个性能损失),当配置服务器缓存时,您仍然会返回 cached 页面。这是避免获取缓存页面的正确方法:curl_setopt($curl1, CURLOPT_HTTPHEADER, array("Cache-Control: no-cache, must-revalidate")
    【解决方案2】:

    避免缓存的最佳方法是将时间或任何其他随机元素应用于 url,如下所示:
    $url .= '?ts=' . time();

    例如,而不是拥有
    http://example.com/content.php
    你会有
    http://example.com/content.php?ts=1212434353

    【讨论】:

    • 这是唯一对我有用的解决方案。我们的网站支持 WAF。
    【解决方案3】:

    curl_setopt($curl1, CURLOPT_FRESH_CONNECT, 1); // 不要使用 url 的缓存版本

    CURLOPT_FRESH_CONNECT TRUE to force use of a new connection instead of a cached one.
    

    检查示例here

    你可以设置标题

    $headers = array( 
                     "Cache-Control: no-cache", 
                    ); 
    curl_setopt($curl1, CURLOPT_HTTPHEADER, $headers);
    

    此链接可能对您有所帮助http://www.php.net/manual/en/function.curl-setopt.php#96903

    【讨论】:

    • 谢谢!向外部服务器发送正确的缓存控制为我解决了这个问题。 (新连接根本没有帮助)curl_setopt($ch, CURLOPT_HTTPHEADER, array("Cache-Control: no-cache")
    【解决方案4】:

    使用 CURLOPT_FRESH_CONNECT - TRUE 强制使用新连接而不是缓存连接。

    示例:

    <?php
        function check_url($url) {
            $c = curl_init();
            curl_setopt($c, CURLOPT_URL, $url);
            curl_setopt($c, CURLOPT_HEADER, 1); // get the header
            curl_setopt($c, CURLOPT_NOBODY, 1); // and *only* get the header
            curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); // get the response as a string from curl_exec(), rather than echoing it
            curl_setopt($c, CURLOPT_FRESH_CONNECT, 1); // don't use a cached version of the url
            if (!curl_exec($c)) { return false; }
    
            $httpcode = curl_getinfo($c, CURLINFO_HTTP_CODE);
            return ($httpcode < 400);
        }
    ?>
    

    有关 curl 的更多详细信息,请查看http://php.net/manual/en/function.curl-setopt.php

    希望对您有所帮助。

    【讨论】:

      【解决方案5】:

      您可以通过将CURLOPT_FRESH_CONNECT 设置为TRUE 来告诉CURL 使用新数据

      您可以在此处阅读有关CURL 功能的更多信息:

      http://php.net/manual/en/function.curl-setopt.php

      【讨论】: