Fixes #8095. Properly handles the case where browser cache needs to be bypassed while server-side logic still delivers proper 304 responses. Unit test added.
This commit is contained in:
parent
e0b1bb8e3d
commit
f43572d3b8
18
src/ajax.js
18
src/ajax.js
|
@ -350,6 +350,8 @@ jQuery.extend({
|
||||||
completeDeferred = jQuery._Deferred(),
|
completeDeferred = jQuery._Deferred(),
|
||||||
// Status-dependent callbacks
|
// Status-dependent callbacks
|
||||||
statusCode = s.statusCode || {},
|
statusCode = s.statusCode || {},
|
||||||
|
// ifModified key
|
||||||
|
ifModifiedKey,
|
||||||
// Headers (they are sent all at once)
|
// Headers (they are sent all at once)
|
||||||
requestHeaders = {},
|
requestHeaders = {},
|
||||||
// Response headers
|
// Response headers
|
||||||
|
@ -453,10 +455,10 @@ jQuery.extend({
|
||||||
if ( s.ifModified ) {
|
if ( s.ifModified ) {
|
||||||
|
|
||||||
if ( ( lastModified = jXHR.getResponseHeader( "Last-Modified" ) ) ) {
|
if ( ( lastModified = jXHR.getResponseHeader( "Last-Modified" ) ) ) {
|
||||||
jQuery.lastModified[ s.url ] = lastModified;
|
jQuery.lastModified[ ifModifiedKey ] = lastModified;
|
||||||
}
|
}
|
||||||
if ( ( etag = jXHR.getResponseHeader( "Etag" ) ) ) {
|
if ( ( etag = jXHR.getResponseHeader( "Etag" ) ) ) {
|
||||||
jQuery.etag[ s.url ] = etag;
|
jQuery.etag[ ifModifiedKey ] = etag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,6 +592,9 @@ jQuery.extend({
|
||||||
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
|
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get ifModifiedKey before adding the anti-cache parameter
|
||||||
|
ifModifiedKey = s.url;
|
||||||
|
|
||||||
// Add anti-cache in url if needed
|
// Add anti-cache in url if needed
|
||||||
if ( s.cache === false ) {
|
if ( s.cache === false ) {
|
||||||
|
|
||||||
|
@ -609,11 +614,12 @@ jQuery.extend({
|
||||||
|
|
||||||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||||||
if ( s.ifModified ) {
|
if ( s.ifModified ) {
|
||||||
if ( jQuery.lastModified[ s.url ] ) {
|
ifModifiedKey = ifModifiedKey || s.url;
|
||||||
requestHeaders[ "if-modified-since" ] = jQuery.lastModified[ s.url ];
|
if ( jQuery.lastModified[ ifModifiedKey ] ) {
|
||||||
|
requestHeaders[ "if-modified-since" ] = jQuery.lastModified[ ifModifiedKey ];
|
||||||
}
|
}
|
||||||
if ( jQuery.etag[ s.url ] ) {
|
if ( jQuery.etag[ ifModifiedKey ] ) {
|
||||||
requestHeaders[ "if-none-match" ] = jQuery.etag[ s.url ];
|
requestHeaders[ "if-none-match" ] = jQuery.etag[ ifModifiedKey ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1867,96 +1867,105 @@ test("data option: empty bodies for non-GET requests", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("jQuery.ajax - If-Modified-Since support", function() {
|
var ifModifiedNow = new Date();
|
||||||
expect( 3 );
|
|
||||||
|
|
||||||
stop();
|
jQuery.each( { " (cache)": true, " (no cache)": false }, function( label, cache ) {
|
||||||
|
|
||||||
var url = "data/if_modified_since.php?ts=" + new Date();
|
test("jQuery.ajax - If-Modified-Since support" + label, function() {
|
||||||
|
expect( 3 );
|
||||||
|
|
||||||
jQuery.ajax({
|
stop();
|
||||||
url: url,
|
|
||||||
ifModified: true,
|
|
||||||
success: function(data, status) {
|
|
||||||
equals(status, "success");
|
|
||||||
|
|
||||||
jQuery.ajax({
|
var url = "data/if_modified_since.php?ts=" + ifModifiedNow++;
|
||||||
url: url,
|
|
||||||
ifModified: true,
|
jQuery.ajax({
|
||||||
success: function(data, status) {
|
url: url,
|
||||||
if ( data === "FAIL" ) {
|
ifModified: true,
|
||||||
ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
|
cache: cache,
|
||||||
ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
|
success: function(data, status) {
|
||||||
} else {
|
equals(status, "success" );
|
||||||
equals(status, "notmodified");
|
|
||||||
ok(data == null, "response body should be empty");
|
jQuery.ajax({
|
||||||
|
url: url,
|
||||||
|
ifModified: true,
|
||||||
|
cache: cache,
|
||||||
|
success: function(data, status) {
|
||||||
|
if ( data === "FAIL" ) {
|
||||||
|
ok(jQuery.browser.opera, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
|
||||||
|
ok(jQuery.browser.opera, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
|
||||||
|
} else {
|
||||||
|
equals(status, "notmodified");
|
||||||
|
ok(data == null, "response body should be empty");
|
||||||
|
}
|
||||||
|
start();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
// Do this because opera simply refuses to implement 304 handling :(
|
||||||
|
// A feature-driven way of detecting this would be appreciated
|
||||||
|
// See: http://gist.github.com/599419
|
||||||
|
ok(jQuery.browser.opera, "error");
|
||||||
|
ok(jQuery.browser.opera, "error");
|
||||||
|
start();
|
||||||
}
|
}
|
||||||
start();
|
});
|
||||||
},
|
},
|
||||||
error: function() {
|
error: function() {
|
||||||
// Do this because opera simply refuses to implement 304 handling :(
|
equals(false, "error");
|
||||||
// A feature-driven way of detecting this would be appreciated
|
// Do this because opera simply refuses to implement 304 handling :(
|
||||||
// See: http://gist.github.com/599419
|
// A feature-driven way of detecting this would be appreciated
|
||||||
ok(jQuery.browser.opera, "error");
|
// See: http://gist.github.com/599419
|
||||||
ok(jQuery.browser.opera, "error");
|
ok(jQuery.browser.opera, "error");
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
equals(false, "error");
|
|
||||||
// Do this because opera simply refuses to implement 304 handling :(
|
|
||||||
// A feature-driven way of detecting this would be appreciated
|
|
||||||
// See: http://gist.github.com/599419
|
|
||||||
ok(jQuery.browser.opera, "error");
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
test("jQuery.ajax - Etag support", function() {
|
test("jQuery.ajax - Etag support" + label, function() {
|
||||||
expect( 3 );
|
expect( 3 );
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
var url = "data/etag.php?ts=" + new Date();
|
var url = "data/etag.php?ts=" + ifModifiedNow++;
|
||||||
|
|
||||||
jQuery.ajax({
|
jQuery.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
ifModified: true,
|
ifModified: true,
|
||||||
success: function(data, status) {
|
cache: cache,
|
||||||
equals(status, "success");
|
success: function(data, status) {
|
||||||
|
equals(status, "success" );
|
||||||
|
|
||||||
jQuery.ajax({
|
jQuery.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
ifModified: true,
|
ifModified: true,
|
||||||
success: function(data, status) {
|
cache: cache,
|
||||||
if ( data === "FAIL" ) {
|
success: function(data, status) {
|
||||||
ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
|
if ( data === "FAIL" ) {
|
||||||
ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
|
ok(jQuery.browser.opera, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
|
||||||
} else {
|
ok(jQuery.browser.opera, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
|
||||||
equals(status, "notmodified");
|
} else {
|
||||||
ok(data == null, "response body should be empty");
|
equals(status, "notmodified");
|
||||||
|
ok(data == null, "response body should be empty");
|
||||||
|
}
|
||||||
|
start();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
// Do this because opera simply refuses to implement 304 handling :(
|
||||||
|
// A feature-driven way of detecting this would be appreciated
|
||||||
|
// See: http://gist.github.com/599419
|
||||||
|
ok(jQuery.browser.opera, "error");
|
||||||
|
ok(jQuery.browser.opera, "error");
|
||||||
|
start();
|
||||||
}
|
}
|
||||||
start();
|
});
|
||||||
},
|
},
|
||||||
error: function() {
|
error: function() {
|
||||||
// Do this because opera simply refuses to implement 304 handling :(
|
// Do this because opera simply refuses to implement 304 handling :(
|
||||||
// A feature-driven way of detecting this would be appreciated
|
// A feature-driven way of detecting this would be appreciated
|
||||||
// See: http://gist.github.com/599419
|
// See: http://gist.github.com/599419
|
||||||
ok(jQuery.browser.opera, "error");
|
ok(jQuery.browser.opera, "error");
|
||||||
ok(jQuery.browser.opera, "error");
|
start();
|
||||||
start();
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
// Do this because opera simply refuses to implement 304 handling :(
|
|
||||||
// A feature-driven way of detecting this would be appreciated
|
|
||||||
// See: http://gist.github.com/599419
|
|
||||||
ok(jQuery.browser.opera, "error");
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue