简体   繁体   English

使用$ .ajax()接收HTTP 304代码

[英]Receive HTTP 304 code with $.ajax()

I am working on an application that loads HTML content into a DIV tag using the jQuery $.ajax() function. 我正在使用jQuery $ .ajax()函数将HTML内容加载到DIV标签中的应用程序。 The $.ajax function is run every few seconds to get updates. $ .ajax函数每隔几秒钟运行一次以获取更新。 The HTML content (a PHP script) is rather large and I do not want to load it into the div unless the content has actually changed since the last load. HTML内容(PHP脚本)相当大,除非从上次加载以来内容实际上已更改,否则我不希望将其加载到div中。 I need to know when a 304 comes back and do nothing - as opposed to loading the HTML into the div from a cache. 我需要知道304何时返回并且什么也不做-与将HTML从缓存加载到div相反。

I have tried setting: 我尝试设置:

ifModified: true

and this doesn't seem to return an error as expected. 并且这似乎没有返回预期的错误。

This leaves me with two questions: 这给我留下了两个问题:

1) Does jQuery think the page is new every time because it's loading a dynamic page - even if the page has not changed since last load? 1)jQuery是否每次都认为该页面是新页面,因为它正在加载动态页面-即使自上次加载以来该页面没有更改过?

2) If no to question 1, then is it possible to make a jQuery $.ajax() call and have the error method execute when a 304 is returned? 2)如果对问题1否,那么是否可以进行jQuery $ .ajax()调用并在返回304时使错误方法执行?

Here is my test code - just to see if I can catch a 304: 这是我的测试代码-只是看我是否能抓到304:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>AJAX Conditional GET Request Test</title>

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

</head>

<body>
<input type="submit" name="button" id="button" value="Check for updates" onclick="javascript:runUpdate();" />
<div id="status" style="width: 100px; height: 12px;"></div>


<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);
            }
        });

    }

    </script>

</body>
</html>

Every time I run the test it says the file has been updated - even when it has not. 每次运行测试时,都会说文件已更新-即使没有更新。

I have also tried using an "If-Modified-Since" using a future date with no success: 我还尝试过使用带有将来日期的“ If-Modified-Since”,但未成功:

headers: {"If-Modified-Since": "Sun, 10 Apr 2016 00:00:00 GMT"}

Server is running: 服务器正在运行:

Apache 2.2.15 (CentOS)
PHP 5.6.17
jQuery 2.1.4

Update: 更新:

I tried making a call to a PHP file the used: 我尝试使用以下方法调用PHP文件:

header("Last-Modified: Fri, 08 Apr 2016 00:00:00 GMT");

to set the Last-Modified to a time in the past. 将Last-Modified设置为过去的时间。 I checked using my browser tools and saw that the Last-Modified was sent. 我使用浏览器工具进行了检查,发现发送了Last-Modified。 5 sequential calls from AJAX to this script did not display an error. 从AJAX到此脚本的5次连续调用未显示错误。

I also read through How to check if jQuery.ajax() request header Status is "304 Not Modified"? 我还通读了如何检查jQuery.ajax()请求标头状态是否为“ 304未修改”? but what it describes seems to run contrary to the jQuery documentation explaining the ifModified argument which reads: 但是它描述的内容似乎与jQuery文档相反,后者解释了ifModified参数,内容为:

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 Last-Modified 
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.

or am I missing something? 还是我错过了什么? According to the linked post I also tried: 根据链接的帖子,我也尝试过:

headers: {"If-Modified-Since": "Fri, 08 Apr 2016 00:00:00 GMT"}

but was not successful. 但没有成功。

https://httpstatuses.com/304 https://httpstatuses.com/304

How to check if jQuery.ajax() request header Status is "304 Not Modified"? 如何检查jQuery.ajax()请求标头状态是否为“ 304未修改”?

jquery will handle a 304 response as it would be a 200 response and therfore your error function will never be called. jQuery将处理304个响应,因为它将处理200个响应,因此永远不会调用您的错误函数。

From what I have found, it is not possible to catch the 304 directly as stated in How to check if jQuery.ajax() request header Status is "304 Not Modified"? 根据我的发现,无法像如何检查jQuery.ajax()请求标头状态是否为“ 304未修改”中所述直接捕获304 , but it is still possible to do an internal comparison of xhr.getResponseHeader("Last-Modified") as retrieved by a HEAD request with a stored value before loading content. ,但仍可以在加载内容之前对HEAD请求所检索的xhr.getResponseHeader(“ Last-Modified”)与存储值进行内部比较。 While this solution does not specifically look at the 304, it does allow a script to decide whether to load content based on it's Last-Modified time instead of loading cached content continuously and wasting resources. 尽管此解决方案未专门针对304,但它确实允许脚本根据上次修改时间来决定是否加载内容,而不是连续加载缓存的内容并浪费资源。

The basis of this idea came from this excellent write-up I found here: http://www.raymondcamden.com/2012/04/05/Using-jQuery-to-conditionally-load-requests/ 这个想法的基础来自我在这里找到的出色文章: http : //www.raymondcamden.com/2012/04/05/Using-jQuery-to-conditionally-load-requests/

Which can also be found here: https://gist.github.com/cfjedimaster/2313466 也可以在这里找到: https : //gist.github.com/cfjedimaster/2313466

However, when I tried the example code in this write-up I came across the problem of my browser caching the HEAD response and always trying to load old content, even when the file had been updated. 但是,当我尝试本文中的示例代码时,遇到了我的浏览器缓存HEAD响应并始终尝试加载旧内容的问题,即使文件已更新也是如此。 In order to make the example work, I added cache:false to the $.ajax() HEAD request call. 为了使示例工作,我向$ .ajax()HEAD请求调用添加了cache:false。

As pointed out by @cmorrissey the PHP script we are checking for updates MUST send a Last-Modified header as such: 正如@cmorrissey所指出的那样,我们正在检查更新的PHP脚本必须发送这样的Last-Modified标头:

header("Last-Modified: Mon, 11 Apr 2016 00:00:00 GMT");

In order to know if the content of the PHP script has changed or not, we can set the Last-Modified via header() using the Last-Modified time of a file the PHP script is loading to generate content. 为了知道PHP脚本的内容是否已更改,我们可以使用PHP脚本加载以生成内容的文件的Last-Modified时间,通过header()设置Last-Modified。 This way, we will always know if the PHP script will have new content. 这样,我们将始终知道PHP脚本是否将具有新内容。 This time can be grabbed using either filemtime() if we are loading the file from disk, or getting the Last-Modified header from the file if we are loading remotely. 如果要从磁盘加载文件,可以使用filemtime()来获取此时间,如果要远程加载,则可以从文件中获取Last-Modified头。

Below is a full, working example minus the PHP script we would be checking for updates (somefile.php) and the JSON or text file it would be checking for updates. 下面是一个完整的工作示例,其中减去了要检查更新的PHP脚本(somefile.php)和要检查更新的JSON或文本文件。

<!DOCTYPE html>
<html>
<head>
<title>AJAX Conditional GET Request Test</title>

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

</head>

<body>
<input type="submit" name="button" id="button" value="Check for updates" onclick="javascript:runUpdate();" />
<div id="status" style="width: 300px; height: 12px;"></div>


<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
            }                    
         });
    }

    </script>

</body>
</html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM