0

这是关于我继承的一些代码;意图很明确,但(至少在 Firefox 和 Chrome 中)它的行为不符合预期。

这个想法显然是基于客户端数据构建 PNG 并缓存它,除非并且直到数据发生变化。其意图大概是保留 PNG 的状态,无论客户端是否使用 cookie、本地存储等,但同时服务器不保留有关此客户端的数据。

客户端 JavaScript:

function read_or_write_png(name, value) {
    // WRITE if value is defined, non-null, etc., get otherwise
    if (value) {
        // WRITE

        // Use cookie to convey new data to server
        document.cookie = 'bx_png=' + value + '; path=/';        

        // bx_png.php generates the image
        // based off of the http cookie and returns it cached
        var img = new Image();
        img.style.visibility = 'hidden';
        img.style.position = 'absolute';
        img.src = 'bx_png.php?name=' + name; // the magic saying "load this".
                                             // 'name' is not consulted server-side,
                                             //  it's here just to get uniqueness
                                             //  for what is cached.
    } else {
        // READ

        // Kill cookie so server should send a 304 header
        document.cookie = 'bx_png=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';

        // load the cached .png
        var img = new Image();
        img.style.visibility = 'hidden';
        img.style.position = 'absolute';
        img.src = 'bx_png.php?name=' + name;            
    }
}

bx_png.php 中的服务器端 PHP:

if (!array_key_exists('bx_png', $_COOKIE) || !isset($_COOKIE['bx_png'])) {
    // we don't have a cookie. Client side code does this on purpose. Force cache.
    header("HTTP/1.1 304 Not Modified");
} else {
    header('Content-Type: image/png');
    header('Last-Modified: Wed, 30 Jun 2010 21:36:48 GMT');
    header('Expires: Tue, 31 Dec 2030 23:30:45 GMT');
    header('Cache-Control: private, max-age=630720000');
    // followed by the content of the PNG        
}

这在第一次写入 PNG 并缓存它时效果很好,但显然目的是能够再次调用它,为同名传递不同的值,并将缓存。在实践中,一旦 PNG 被缓存,就会出现(通过 Fiddler)根本没有调用服务器。也就是说,在尝试读取时,浏览器不会访问服务器并返回 304,而是直接从缓存中获取内容,而无需与服务器通信。就其本身而言,该部分是无害的,但当然有害的是在尝试写入时会发生同样的事情,并且服务器永远没有机会根据新值发回不同的 PNG。

有谁知道如何调整它以实现其明显的意图?也许标题中有些不同?也许某种从客户端清除缓存的方法?也许完全是我没有想到的其他东西?在服务器端和客户端方面,我都是一个非常扎实的开发人员,但在围绕 HTTP 协议本身这样的技巧方面经验不足。

4

2 回答 2

2

您需要添加must-revalidate到您的Cache-Control标题以告诉浏览器这样做。

于 2013-10-21T16:41:12.243 回答
0

试试cache-control: no-store,因为它在 Safari/WebKit 中为我解决了同样的问题。(我认为 Chrome 在您提出问题后就修复了它。)

它仍然是一个开放的 WebKit 错误,但他们为此标头添加了修复程序。

于 2015-07-21T22:11:00.967 回答