I'm using jQuery ajax to retrieve json from an ASP.Net MVC app and I'm not seeing expected results when making ajax calls where ifModified = true
.
I'm using jQuery 1.9.1 and Chrome Version 26.0.1410.64 m
When using a new browser instance and making the initial request for content that is already cached, a call to the server to check the cache status is never made even though ifModified=true is set in the ajax config. On subsequent requests from the same browser instance, a call to the server is (expectedly) made to which the server responds with a 304.
On the initial request, the browser network trace shows the content was delivered from cache with a status 200 even though the modified date was never checked. Fiddler shows no request was made, and a breakpoint in the ASP.Net MVC Controller is not hit.
Is this a bug, or is there a way to get this to work properly? If it's a bug, is it a jQuery bug or a Chrome bug?
Here's a simplified ajax call:
var req = $.ajax({
type: "GET",
dataType: "json",
url: "/JsonTest/GetJson",
ifModified: true,
success: function (data, status, jqXHR) {
if (data === undefined && status == "notmodified") {
$.ajax({
type: this.type,
dataType: this.dataType,
url: this.url,
ifModified: false,
success: this.success,
error: this.error,
complete: this.complete
});
} else {
alert($.toJSON(data));
}
},
error: function (jqXHR, status, error) {
alert(error);
},
complete: function (jqXHR, status) {
}
});
Here's a simplified ASP.Net MVC controller method:
[AllowAnonymous]
public ActionResult GetJson()
{
// dummy data version.
var currentVersion = new DateTime(2013, 04, 30, 12, 0, 0);
// get client cached version from request
DateTime cachedVersion;
if (DateTime.TryParseExact(HttpContext.Request.Headers["If-Modified-Since"], "r", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out cachedVersion))
{
cachedVersion = cachedVersion.ToLocalTime();
}
else
{
cachedVersion = DateTime.MinValue;
}
// return 304 if not changed
if (currentVersion.Subtract(cachedVersion).Duration() < TimeSpan.FromSeconds(1))
{
HttpContext.Response.StatusCode = 304;
HttpContext.Response.StatusDescription = "Not Modified";
return new EmptyResult();
}
// still here? return current object and set current version response header
var rv = new { name = "Hello", value = "World" };
HttpContext.Response.Cache.SetCacheability(HttpCacheability.Private);
HttpContext.Response.Cache.SetLastModified(currentVersion);
return Json(rv, JsonRequestBehavior.AllowGet);
}
Steps to reproduce: 1) start new browser instance 2) initiate ajax request 3) close response alert window 4) initiate ajax request 5) close browser repeat
Very first time through, empty cache: step 2 issues request to server. Server responds with a 200. step 4 issues request to server, server responds 304.
Second time through - response in cache: step 2 DOES NOT issue request to server. Response is taken from cache with a 200 status. step 4 issues request to server, server responds 304.
I would expect step #2 on the second time through to issue a request to the server and receive a 304.
This failure to check the status of a cached source every time it's used is a big problem as cached data may be stale but the user won't know it until they issue a subsequent request in the same browser instance.