关于 php:使用 $.ajax() 接收 HTTP 304 代码 | 珊瑚贝

Receive HTTP 304 code with $.ajax()


我正在开发一个使用 jQuery $.ajax() 函数将 HTML 内容加载到 DIV 标记中的应用程序。 $.ajax 函数每隔几秒运行一次以获取更新。 HTML 内容(一个 PHP 脚本)相当大,我不想将它加载到 div 中,除非自上次加载后内容实际发生了变化。我需要知道 304 何时返回并且什么都不做 – 而不是将 HTML 从缓存加载到 div 中。

我试过设置:

1
ifModified: true

这似乎没有按预期返回错误。

这给我留下了两个问题:

1) jQuery 是否每次都认为页面是新的,因为它正在加载一个动态页面——即使该页面自上次加载以来没有改变?

2) 如果问题 1 没有,那么是否可以进行 jQuery $.ajax() 调用并在返回 304 时执行错误方法?

这是我的测试代码 – 只是想看看我是否能捕捉到 304:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!DOCTYPE html>
<html>
<head>
<meta httpequiv=“Content-Type” content=“text/html; charset=utf-8” />
AJAX Conditional GET Request Test

<script type=“text/javascript” src=“../jquery/jquery-2.1.4.min.js”>

</head>

<body>
<input type=“submit” name=“button” id=“button” value=“Check for updates” onclick=“javascript:runUpdate();” />

<script type=“text/javascript”>

    function runUpdate()
    {

        var today = new Date();
        var h = today.getHours();
        var m = today.getMinutes();
        var s = today.getSeconds();

        var time = h+“:”+m+“:”+s;

        $.ajax({
            type:“GET”,
            url:“../dir/phpscriptthatsometimesupdates.php”,
            ifModified: true,
            success: function(data){
                $(“#status”).html(“Updated”+time);
            },
            error: function(data, status, error){
                $(“#status”).html(“Not updated”+time);
            }
        });

    }

   

</body>
</html>

每次我运行测试时,它都会说文件已更新——即使它没有更新。

我也尝试过使用”If-Modified-Since”,但没有成功:

1
headers: {“If-Modified-Since”:“Sun, 10 Apr 2016 00:00:00 GMT”}

服务器正在运行:

1
2
3
Apache 2.2.15 (CentOS)
PHP 5.6.17
jQuery 2.1.4

更新:

我尝试调用使用的 PHP 文件:

1
header(“Last-Modified: Fri, 08 Apr 2016 00:00:00 GMT”);

将 Last-Modified 设置为过去的时间。我使用浏览器工具进行了检查,发现 Last-Modified 已发送。从 AJAX 对该脚本的 5 次连续调用未显示错误。

我还阅读了如何检查 jQuery.ajax() 请求标头状态是否为”304 未修改”?但它所描述的似乎与解释 ifModified 参数的 jQuery 文档相反:

1
2
3
4
5
6
7
ifModified (default: false)
Type: Boolean
Allow the request to be successful only if the response has changed
since the last request. This is done by checking the LastModified
header. Default value is false, ignoring the header. In jQuery 1.4 this
technique also checks the ‘etag’ specified by the server to catch
unmodified data.

还是我错过了什么?根据链接的帖子,我也尝试过:

1
headers: {“If-Modified-Since”:“Fri, 08 Apr 2016 00:00:00 GMT”}

但没有成功。

  • 您需要使用标题 Last-Modified:
  • @cmorrissey 不会由 Apache 发布吗?或者这不会自动发生?
  • 它通常不会发生在 .php 文件上,因为它们被视为动态内容。使用浏览器中的开发工具查看服务器发送的标头。您会注意到大多数其他文件都有它,但您的 php 文件不会。
  • 啊哈!这是有道理的——我会尝试并发布结果!


根据我的发现,无法直接捕获 304,如 How to check if jQuery.ajax() request header Status is”304 Not Modified”? 中所述,但仍然可以进行内部将 HEAD 请求检索到的 xhr.getResponseHeader(“Last-Modified”) 与加载内容之前存储的值进行比较。虽然此解决方案没有专门针对 304,但它确实允许脚本根据其 Last-Modified 时间来决定是否加载内容,而不是连续加载缓存的内容并浪费资源。


这个想法的基础来自我在这里找到的这篇出色的文章:http://www.raymondcamden.com/2012/04/05/Using-jQuery-to-conditionally-load-requests/

也可以在这里找到:https://gist.github.com/cfjedimaster/2313466

但是,当我尝试这篇文章中的示例代码时,我遇到了浏览器缓存 HEAD 响应并总是尝试加载旧内容的问题,即使文件已更新也是如此。为了使示例正常工作,我在 $.ajax() HEAD 请求调用中添加了 cache:false。

正如@cmorrissey 所指出的,我们正在检查更新的 PHP 脚本必须发送一个 Last-Modified 标头,如下所示:

1
header(“Last-Modified: Mon, 11 Apr 2016 00:00:00 GMT”);

为了知道 PHP 脚本的内容是否发生了变化,我们可以通过 header() 设置 Last-Modified,使用 PHP 脚本正在加载的文件的 Last-Modified 时间来生成内容。这样,我们将始终知道 PHP 脚本是否会有新内容。如果我们正在从磁盘加载文件,则可以使用 filemtime() 来获取这个时间,或者如果我们正在远程加载,则可以从文件中获取 Last-Modified 标头。

下面是一个完整的工作示例,减去了我们将检查更新的 PHP 脚本 (somefile.php) 以及它将检查更新的 JSON 或文本文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<!DOCTYPE html>
<html>
<head>
AJAX Conditional GET Request Test

<script type=“text/javascript” src=“jquery-2.1.4.min.js”>

</head>

<body>
<input type=“submit” name=“button” id=“button” value=“Check for updates” onclick=“javascript:runUpdate();” />

<script type=“text/javascript”>

    var resourceLastTime =“”;

    function runUpdate()
    {

        var today = new Date();
        var h = today.getHours();
        var m = today.getMinutes();
        var s = today.getSeconds();
        var time = h+“:”+m+“:”+s;

        var resourceUrl =“somefile.php”;

        if(resourceLastTime !=“”)
        {
            $.ajax({
                type:“HEAD”,
                url: resourceUrl,
                cache: false,
                success: function(res,code,xhr){

                    if(resourceLastTime != xhr.getResponseHeader(“Last-Modified”))
                    {
                        getUrl(resourceUrl);
                        $(“#status”).html(“Updated”+time);
                    }
                    else
                    {
                        $(“#status”).html(“Not updated”+time);
                    }
                },
                error: function(data, status, error){
                    $(“#status”).html(error+“”+status+“”+time);
                }
            });
        }
        else
        {
            getUrl(resourceUrl);
            $(“#status”).html(“First load”+time);
        }
    }

    function getUrl(urlToGet)
    {
        var urlContents =“”;

        $.ajax({
            url:urlToGet,
            type:“get”,
            cache:false,
            success:function(res,code,xhr) {
                resourceLastTime = xhr.getResponseHeader(“Last-Modified”);
                //must process res here due to asynchronous nature of $.ajax() function
            }                    
         });
    }

   

</body>
</html>

  • 看起来这是唯一可行的解??决方案,但实际上 Last-Modified 可能不存在作为响应。即使它存在,缓存的资源也将具有相同的 Last-Modified 日期。但是您真正可以检查的是 d Date 标头,它始终设置为生成响应的日期。


https://httpstatuses.com/304

如何检查 jQuery.ajax() 请求头状态是否为”304 Not Modified”?

jquery 将处理 304 响应,因为它将是 200 响应,因此您的错误函数将永远不会被调用。

  • 如果链接内容发生变化,仅链接答案将无济于事。提供答案中的重要部分。


来源:https://www.codenong.com/36509073/

微信公众号
手机浏览(小程序)

Warning: get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(): Failed to enable crypto in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(https://static.shanhubei.com/qrcode/qrcode_viewid_9215.jpg): failed to open stream: operation failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57
0
分享到:
没有账号? 忘记密码?