【问题标题】:Safari 5.1.7 mixing headers from content to page?Safari 5.1.7 混合标题从内容到页面?
【发布时间】:2012-07-17 11:57:32
【问题描述】:

下面这个简单的 php 页面保存在我的网络服务器的根目录中作为test.php,我遇到了一个非常奇怪的问题:

<?
if( $_GET['img'] ) {
    header('HTTP/1.0 304 Not Modified');
    die();
} else {
    header("Cache-Control: no-store, no-cache, must-revalidate");
}
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<body>

<img src="/test.php?img=1">
<a href="/not_existent_page.php">Dead link</a>

</body>
</html>

所以当页面被加载时,我的服务器会响应以下标题:

Status Code 200
Cache-Control   no-store, no-cache, must-revalidate
Content-Type    text/html; charset=utf-8
Date    Wed, 18 Jul 2012 12:00:43 GMT
Server  Apache/2.2.22 (Ubuntu)
Strict-Transport-Security   max-age=172800, includeSubDomains
Vary    Accept-Encoding
x-frame-options sameorigin
x-powered-by    PHP/5.4.4-1~precise+1
x-ua-compatible IE=edge

有趣的部分是缓存头:它说,不要缓存!

页面加载后对图片的请求有如下响应头:

Status Code 304
Date    Wed, 18 Jul 2012 12:02:20 GMT
Server  Apache/2.2.22 (Ubuntu)

它没有说任何关于缓存的内容(但这无所谓,我测试过)。

使用 firefox 和 chrome,网站的行为应该是这样的:每次我重新加载页面时,它都会按应有的方式重新加载。如果我点击链接,我会收到 404 apache 错误。

使用 safari,会发生以下情况:

如果我先打开页面,我会看到它。 当我在短时间内重新加载页面时(请参阅下文“短时间”的含义),它总是给我一个空白站点,当我点击它并出现死链接时它有时给了我一个空白网站,但我在 safari 的 Web 开发人员控制台中看到以下标题:

Status Code 304
Connection:Keep-Alive
Date:Wed, 18 Jul 2012 12:07:41 GMT
Keep-Alive:timeout=15, max=99
Server:Apache/2.2.22 (Ubuntu)
Vary:Accept-Encoding

页面保持空白!但是:在我的 apache 服务器日志中,它说它在页面重新加载时返回了状态代码 200 的一切正常:

// first page load
[18/Jul/2012:14:10:12 +0200] "GET /test.php HTTP/1.1" 200 979 "url/test.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2"

// request of picture with answer 304
[18/Jul/2012:14:10:12 +0200] "GET /test.php?img=1 HTTP/1.1" 304 266 "url/test.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2"

// reload within 10 seconds
[18/Jul/2012:14:10:19 +0200] "GET /test.php HTTP/1.1" 200 777 "url/test.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2"

(点击死链接时会出现 404。)

现在有趣的部分来了:如果我等一下。加载页面 10 多秒后,Safari 的行为符合预期:它只是在重新加载时再次加载页面而没有 304 标题(或在死链接上显示 404)。

我对 Firefox 和 chrome 完全没有问题。

所以我的问题是:Safari 是否混淆了页面的标题,但仅在再次加载页面/在 10 秒内单击链接时才发生?我怎样才能防止这种情况?这是 Safari 中的错误吗?

顺便说一句:如果我将标头更改为其他内容,Safari 会缓存该标头。因此,如果我像这样更改 test.php:

...
if( $_GET['img'] ) {
    header('HTTP/1.0 204 No Content');
    die();
} else {
....

页面重新加载现在只是中止而没有做任何事情,但我在 safari 控制台中看到的标题是 204 No Content

最后一件事:在 10 秒内重新加载页面会不断触发错误,而有时点击链接在 safari 中有效,有时则无效。

【问题讨论】:

    标签: safari http-headers browser-cache


    【解决方案1】:

    /test.php 将始终设置 header("Cache-Control: no-store, no-cache, must-revalidate"); 标头说 do not cache 没有什么有趣的,因为您明确设置了这些标头。

    /test.php?img=whatever 永远不会像上面那样设置 Cache-Control 标头,并且总是返回空白 304 Not Modified。您在 header() 调用后立即退出。从技术上讲,它不是 apache 的图像。它的 mime 类型将是 text/html,因此它会将您的过期/缓存作为 html 和 php(在您的 .conf 和/或 htaccess 中)。除非您使用header('Content-Type: image/jpeg', true); 或类似的方式。

    在某些情况下,也可以使用 header() 的第二个参数来替换之前的参数。

    试试这个。如果你得到相同的结果,请告诉我

    <?php
    if (isset($_GET['img'])) {
        header('Content-Type: image/jpeg', true);
        header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified', true, 304);
        exit;
    } else {
        header('Expires: -1', true);
        header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0', true);
    }
    ?>
    

    【讨论】:

    • 修复它的是Content-Type: image/jpeg。我不知道为什么这只对 safari 5.1.7 是必需的,看起来它无法处理缺少的 Content-Type 标头并将事情搞混了。因为我的服务器从来没有为304 请求发送任何Content-Type(我发布了唯一的标题回到我的问题中)。 Safari 6 已经修复了这个问题。
    猜你喜欢
    • 1970-01-01
    • 2015-07-21
    • 2020-04-28
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多