我正在开发一个应用程序,它使用jQuery $ .ajax()函数将HTML内容加载到DIV标记中。 $ .ajax函数每隔几秒运行一次以获得更新。 HTML内容(PHP脚本)相当大,我不想将其加载到div中,除非内容自上次加载后实际发生了更改。我需要知道304何时返回并且什么都不做 - 而不是将HTML从缓存加载到div中。
我尝试过设置:
ifModified: true
并且这似乎没有按预期返回错误。
这给我留下了两个问题:
1)jQuery是否认为该页面每次都是新的,因为它正在加载动态页面 - 即使页面自上次加载后没有改变?
2)如果不回答问题1,那么是否可以进行jQuery $ .ajax()调用并在返回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>
每次我运行测试时都会说文件已经更新 - 即使它没有。
我还尝试使用“If-Modified-Since”使用未来日期但没有成功:
headers: {"If-Modified-Since": "Sun, 10 Apr 2016 00:00:00 GMT"}
服务器正在运行:
Apache 2.2.15 (CentOS)
PHP 5.6.17
jQuery 2.1.4
更新
我尝试调用使用过的PHP文件:
header("Last-Modified: Fri, 08 Apr 2016 00:00:00 GMT");
将Last-Modified设置为过去的时间。我使用浏览器工具进行了检查,发现Last-Modified已发送。从AJAX到此脚本的5次连续调用未显示错误。
我也阅读了How to check if jQuery.ajax() request header Status is "304 Not Modified"?,但它描述的内容似乎与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.
或者我错过了什么?根据链接的帖子,我也尝试过:
headers: {"If-Modified-Since": "Fri, 08 Apr 2016 00:00:00 GMT"}
但没有成功。
答案 0 :(得分:0)
How to check if jQuery.ajax() request header Status is "304 Not Modified"?
jquery将处理304响应,因为它将是200响应,因此永远不会调用您的错误函数。
答案 1 :(得分:0)
根据我的发现,不可能像How to check if jQuery.ajax() request header Status is "304 Not Modified"?中所述直接捕获304,但仍然可以对xhr.getResponseHeader进行内部比较(&#34; Last-Modified&# 34;)由加载内容之前具有存储值的HEAD请求检索。虽然此解决方案没有专门查看304,但它确实允许脚本根据它的最后修改时间来决定是否加载内容,而不是连续加载缓存内容并浪费资源。
这个想法的基础来自我在这里找到的优秀写作: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标头:
header("Last-Modified: Mon, 11 Apr 2016 00:00:00 GMT");
为了知道PHP脚本的内容是否发生了变化,我们可以使用PHP脚本加载的文件的Last-Modified时间来设置Last-Modified via header()以生成内容。这样,我们将始终知道PHP脚本是否具有新内容。如果我们从磁盘加载文件,则可以使用filemtime()获取此时间;如果我们正在远程加载,则可以从文件中获取Last-Modified标头。
下面是一个完整的,有效的示例,减去我们要检查更新的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>