Skip to content

Commit e077ffb

Browse files
committed
Ajax: Preserve URL hash on requests
Fixes jquerygh-1732 Closes jquerygh-2721
1 parent eaa3e9f commit e077ffb

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

src/ajax.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,9 @@ jQuery.extend( {
415415
// Loop variable
416416
i,
417417

418+
// uncached part of the url
419+
uncached,
420+
418421
// Create the final options object
419422
s = jQuery.ajaxSetup( {}, options ),
420423

@@ -516,11 +519,10 @@ jQuery.extend( {
516519
// Attach deferreds
517520
deferred.promise( jqXHR );
518521

519-
// Remove hash character (#7531: and string promotion)
520522
// Add protocol if not provided (prefilters might expect it)
521523
// Handle falsy url in the settings object (#10093: consistency with old signature)
522524
// We also use the url parameter if available
523-
s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
525+
s.url = ( ( url || s.url || location.href ) + "" )
524526
.replace( rprotocol, location.protocol + "//" );
525527

526528
// Alias method option to type as per ticket #12004
@@ -581,30 +583,32 @@ jQuery.extend( {
581583

582584
// Save the URL in case we're toying with the If-Modified-Since
583585
// and/or If-None-Match header later on
584-
cacheURL = s.url;
586+
// Remove hash to simplify url manipulation
587+
cacheURL = s.url.replace( rhash, "" );
585588

586589
// More options handling for requests with no content
587590
if ( !s.hasContent ) {
588591

592+
// Remember the hash so we can put it back
593+
uncached = s.url.slice( cacheURL.length );
594+
589595
// If data is available, append data to url
590596
if ( s.data ) {
591-
cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
597+
cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
592598

593599
// #9682: remove data so that it's not used in an eventual retry
594600
delete s.data;
595601
}
596602

597-
// Add anti-cache in url if needed
603+
// Add anti-cache in uncached url if needed
598604
if ( s.cache === false ) {
599-
s.url = rts.test( cacheURL ) ?
600-
601-
// If there is already a '_' parameter, set its value
602-
cacheURL.replace( rts, "$1_=" + nonce++ ) :
603-
604-
// Otherwise add one to the end
605-
cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
605+
cacheURL = cacheURL.replace( rts, "" );
606+
uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
606607
}
607608

609+
// Put hash and anti-cache on the URL that will be requested (gh-1732)
610+
s.url = cacheURL + uncached;
611+
608612
// Change '%20' to '+' if this is encoded form body content (gh-2658)
609613
} else if ( s.data && s.processData &&
610614
( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {

test/unit/ajax.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,20 +328,20 @@ QUnit.module( "ajax", {
328328
};
329329
} );
330330

331-
ajaxTest( "jQuery.ajax() - hash", 3, function( assert ) {
331+
ajaxTest( "jQuery.ajax() - hash", 4, function( assert ) {
332332
return [
333333
{
334334
url: "data/name.html#foo",
335335
beforeSend: function( xhr, settings ) {
336-
assert.equal( settings.url, "data/name.html", "Make sure that the URL is trimmed." );
336+
assert.equal( settings.url, "data/name.html#foo", "Make sure that the URL has its hash." );
337337
return false;
338338
},
339339
error: true
340340
},
341341
{
342342
url: "data/name.html?abc#foo",
343343
beforeSend: function( xhr, settings ) {
344-
assert.equal( settings.url, "data/name.html?abc", "Make sure that the URL is trimmed." );
344+
assert.equal( settings.url, "data/name.html?abc#foo", "Make sure that the URL has its hash." );
345345
return false;
346346
},
347347
error: true
@@ -352,7 +352,21 @@ QUnit.module( "ajax", {
352352
"test": 123
353353
},
354354
beforeSend: function( xhr, settings ) {
355-
assert.equal( settings.url, "data/name.html?abc&test=123", "Make sure that the URL is trimmed." );
355+
assert.equal( settings.url, "data/name.html?abc&test=123#foo", "Make sure that the URL has its hash." );
356+
return false;
357+
},
358+
error: true
359+
},
360+
{
361+
url: "data/name.html?abc#brownies",
362+
data: {
363+
"devo": "hat"
364+
},
365+
cache: false,
366+
beforeSend: function( xhr, settings ) {
367+
// Remove the random number, but ensure the cashe-buster param is there
368+
var url = settings.url.replace( /\d+/, "" );
369+
assert.equal( url, "data/name.html?abc&devo=hat&_=#brownies", "Make sure that the URL has its hash." );
356370
return false;
357371
},
358372
error: true

0 commit comments

Comments
 (0)