Skip to content

Commit bbeb696

Browse files
committed
Merge branch 'abort-xhr'
2 parents d3e5570 + a2ae3d3 commit bbeb696

File tree

2 files changed

+56
-5
lines changed

2 files changed

+56
-5
lines changed

jquery.pjax.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,7 @@ function pjax(options) {
349349
}
350350

351351
// Cancel the current request if we're already pjaxing
352-
var xhr = pjax.xhr
353-
if ( xhr && xhr.readyState < 4) {
354-
xhr.onreadystatechange = $.noop
355-
xhr.abort()
356-
}
352+
abortXHR(pjax.xhr)
357353

358354
pjax.options = options
359355
var xhr = pjax.xhr = $.ajax(options)
@@ -420,6 +416,12 @@ if ('state' in window.history) {
420416
// You probably shouldn't use pjax on pages with other pushState
421417
// stuff yet.
422418
function onPjaxPopstate(event) {
419+
420+
// Hitting back or forward should override any pending PJAX request.
421+
if (!initialPop) {
422+
abortXHR(pjax.xhr)
423+
}
424+
423425
var previousState = pjax.state
424426
var state = event.state
425427

@@ -536,6 +538,15 @@ function fallbackPjax(options) {
536538
form.submit()
537539
}
538540

541+
// Internal: Abort an XmlHttpRequest if it hasn't been completed,
542+
// also removing its event handlers.
543+
function abortXHR(xhr) {
544+
if ( xhr && xhr.readyState < 4) {
545+
xhr.onreadystatechange = $.noop
546+
xhr.abort()
547+
}
548+
}
549+
539550
// Internal: Generate unique id for state object.
540551
//
541552
// Use a timestamp instead of a counter since ids should still be

test/unit/pjax.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,46 @@ if ($.support.pjax) {
845845
}, 0)
846846
}
847847

848+
asyncTest("clicking back while loading cancels XHR", function() {
849+
var frame = this.frame
850+
851+
frame.$('#main').on('pjax:timeout', function(event) {
852+
event.preventDefault()
853+
})
854+
855+
frame.$("#main").one('pjax:send', function() {
856+
857+
// Check that our request is aborted (need to check
858+
// how robust this is across browsers)
859+
frame.$("#main").one('pjax:complete', function(e, xhr, textStatus) {
860+
equal(xhr.status, 0)
861+
equal(textStatus, 'abort')
862+
})
863+
864+
setTimeout(function() {
865+
frame.history.back()
866+
}, 250)
867+
868+
// Make sure the URL and content remain the same after the
869+
// XHR would have arrived (delay on timeout.html is 1s)
870+
setTimeout(function() {
871+
var afterBackLocation = frame.location.pathname
872+
var afterBackTitle = frame.document.title
873+
874+
setTimeout(function() {
875+
equal(frame.location.pathname, afterBackLocation)
876+
equal(frame.document.title, afterBackTitle)
877+
start()
878+
}, 1000)
879+
}, 500)
880+
})
881+
882+
frame.$.pjax({
883+
url: "timeout.html",
884+
container: "#main"
885+
})
886+
})
887+
848888
asyncTest("popstate going back to page", function() {
849889
var frame = this.frame
850890

0 commit comments

Comments
 (0)