关于 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"}

但没有成功。


根据我的发现,无法直接捕获 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>


https://httpstatuses.com/304

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

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


原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/268505.html

(0)
上一篇 2022年6月20日
下一篇 2022年6月20日

相关推荐

发表回复

登录后才能评论