File tree Expand file tree Collapse file tree 2 files changed +59
-5
lines changed Expand file tree Collapse file tree 2 files changed +59
-5
lines changed Original file line number Diff line number Diff line change @@ -331,11 +331,7 @@ function pjax(options) {
331331 }
332332
333333 // Cancel the current request if we're already pjaxing
334- var xhr = pjax . xhr
335- if ( xhr && xhr . readyState < 4 ) {
336- xhr . onreadystatechange = $ . noop
337- xhr . abort ( )
338- }
334+ abortXHR ( pjax . xhr )
339335
340336 pjax . options = options
341337 var xhr = pjax . xhr = $ . ajax ( options )
@@ -402,6 +398,12 @@ if ('state' in window.history) {
402398// You probably shouldn't use pjax on pages with other pushState
403399// stuff yet.
404400function onPjaxPopstate ( event ) {
401+
402+ // Hitting back or forward should override any pending PJAX request.
403+ if ( ! initialPop ) {
404+ abortXHR ( pjax . xhr )
405+ }
406+
405407 var state = event . state
406408
407409 if ( state && state . container ) {
@@ -504,6 +506,15 @@ function fallbackPjax(options) {
504506 form . submit ( )
505507}
506508
509+ // Internal: Abort an XmlHttpRequest if it hasn't been completed,
510+ // also removing its event handlers.
511+ function abortXHR ( xhr ) {
512+ if ( xhr && xhr . readyState < 4 ) {
513+ xhr . onreadystatechange = $ . noop
514+ xhr . abort ( )
515+ }
516+ }
517+
507518// Internal: Generate unique id for state object.
508519//
509520// Use a timestamp instead of a counter since ids should still be
Original file line number Diff line number Diff line change @@ -749,6 +749,49 @@ if ($.support.pjax) {
749749 } , 0 )
750750 }
751751
752+ asyncTest ( "clicking back while loading cancels XHR" , function ( ) {
753+ var frame = this . frame
754+
755+ frame . $ ( "#main" ) . one ( 'pjax:complete' , function ( ) {
756+
757+ frame . $ ( "#main" ) . one ( 'pjax:send' , function ( ) {
758+
759+ // Check that our request is aborted (need to check
760+ // how robust this is across browsers)
761+ frame . $ ( "#main" ) . one ( 'pjax:complete' , function ( e , xhr , textStatus ) {
762+ equal ( xhr . status , 0 )
763+ equal ( textStatus , 'abort' )
764+ } )
765+
766+ // Make sure the URL and content remain the same after the
767+ // XHR would have arrived (delay on timeout.html is 1s)
768+ setTimeout ( function ( ) {
769+ var afterBackLocation = frame . location . pathname
770+ var afterBackTitle = frame . document . title
771+
772+ setTimeout ( function ( ) {
773+ equal ( frame . location . pathname , afterBackLocation )
774+ equal ( frame . document . title , afterBackTitle )
775+ start ( )
776+ } , 1000 )
777+ } , 500 )
778+
779+ frame . history . back ( )
780+
781+ } )
782+
783+ frame . $ . pjax ( {
784+ url : "timeout.html" ,
785+ container : "#main"
786+ } )
787+ } )
788+
789+ frame . $ . pjax ( {
790+ url : "hello.html" ,
791+ container : "#main"
792+ } )
793+ } )
794+
752795 asyncTest ( "popstate going back to page" , function ( ) {
753796 var frame = this . frame
754797
You can’t perform that action at this time.
0 commit comments