Merge pull request #114 from MoOx/fix/abort-pending-xhr

Abort previous pending XHR when navigating
This commit was merged in pull request #114.
This commit is contained in:
BehindTheMath
2018-01-24 18:54:33 -05:00
committed by GitHub
8 changed files with 95 additions and 8 deletions

View File

@@ -10,7 +10,7 @@
<div class='body'>
<h1>Index</h1>
Hello.
Go to <a href='page2.html' class="js-Pjax">Page 2</a> and view your console to see Pjax events.
Go to <a href='page2.html' class="js-Pjax">Page 2</a> or <a href='page3.html' class="js-Pjax">Page 3</a> and view your console to see Pjax events.
Clicking on <a href='index.html'>this page</a> will just reload the page entirely.
</div>
</body>

15
example/page3.html Normal file
View File

@@ -0,0 +1,15 @@
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<title>Hello</title>
<script src='../pjax.js'></script>
<script src='example.js'></script>
</head>
<body>
<div class='body'>
<h1>Page 3</h1>
Hello. Go to <a href='index.html' class="js-Pjax">Index</a>.
</div>
</body>
</html>

View File

@@ -5,6 +5,8 @@ var forEachEls = require("./lib/foreach-els.js")
var newUid = require("./lib/uniqueid.js")
var noop = require("./lib/util/noop")
var on = require("./lib/events/on.js")
// var off = require("./lib/events/on.js")
var trigger = require("./lib/events/trigger.js")
@@ -145,16 +147,21 @@ Pjax.prototype = {
// }
},
doRequest: require("./lib/request.js"),
abortRequest: require("./lib/abort-request.js"),
doRequest: require("./lib/send-request.js"),
loadUrl: function(href, options) {
this.log("load href", href, options)
// Abort any previous request
this.abortRequest(this.request)
trigger(document, "pjax:send", options);
// Do the request
options.requestOptions.timeout = this.options.timeout
this.doRequest(href, options.requestOptions, function(html, request) {
this.request = this.doRequest(href, options.requestOptions, function(html, request) {
// Fail if unable to load HTML via AJAX
if (html === false) {
trigger(document,"pjax:complete pjax:error", options)
@@ -326,10 +333,10 @@ if (Pjax.isSupported()) {
}
// if there isnt required browser functions, returning stupid api
else {
var stupidPjax = function() {}
var stupidPjax = noop
for (var key in Pjax.prototype) {
if (Pjax.prototype.hasOwnProperty(key) && typeof Pjax.prototype[key] === "function") {
stupidPjax[key] = stupidPjax
stupidPjax[key] = noop
}
}

8
lib/abort-request.js Normal file
View File

@@ -0,0 +1,8 @@
var noop = require("./util/noop")
module.exports = function(request) {
if (request && request.readyState < 4) {
request.onreadystatechange = noop
request.abort()
}
}

1
lib/util/noop.js Normal file
View File

@@ -0,0 +1 @@
module.exports = function() {}

View File

@@ -0,0 +1,56 @@
var tape = require("tape")
var abortRequest = require("../../lib/abort-request.js")
var sendRequest = require("../../lib/send-request.js")
// Polyfill responseURL property into XMLHttpRequest if it doesn't exist,
// just for the purposes of this test
// This polyfill is not complete; it won't show the updated location if a
// redirection occurred, but it's fine for our purposes.
if (!("responseURL" in XMLHttpRequest.prototype)) {
var nativeOpen = XMLHttpRequest.prototype.open
XMLHttpRequest.prototype.open = function(method, url) {
this.responseURL = url
return nativeOpen.apply(this, arguments)
}
}
tape("test aborting xhr request", function(t) {
var requestCacheBust = sendRequest.bind({
options: {
cacheBust: true,
},
})
t.test("- pending request is aborted", function(t) {
var r = requestCacheBust("https://httpbin.org/delay/10", {}, function() {
t.fail("xhr was not aborted")
})
t.equal(r.readyState, 1, "xhr readyState is '1' (SENT)")
abortRequest(r)
t.equal(r.readyState, 0, "xhr readyState is '0' (ABORTED)")
t.equal(r.status, 0, "xhr HTTP status is '0' (ABORTED)")
t.equal(r.responseText, "", "xhr response is empty")
t.end()
})
t.test("- request is not aborted if it has already completed", function(t) {
var r = requestCacheBust("https://httpbin.org/get", {}, function() {
abortRequest(r)
t.equal(r.readyState, 4, "xhr readyState is '4' (DONE)")
t.equal(r.status, 200, "xhr HTTP status is '200' (OK)")
t.end()
})
})
t.test("- request is not aborted if it is undefined", function(t) {
var r
try {
abortRequest(r)
}
catch (e) {
t.fail("aborting an undefined request threw an error")
}
t.equal(typeof r, "undefined", "undefined xhr was ignored")
t.end()
})
t.end()
})

View File

@@ -1,6 +1,6 @@
var tape = require("tape")
var request = require("../../lib/request.js")
var sendRequest = require("../../lib/send-request.js")
// Polyfill responseURL property into XMLHttpRequest if it doesn't exist,
// just for the purposes of this test
@@ -18,7 +18,7 @@ tape("test xhr request", function(t) {
var url = "https://httpbin.org/get"
t.test("- request is made, gets a result, and is cache-busted", function(t) {
var requestCacheBust = request.bind({
var requestCacheBust = sendRequest.bind({
options: {
cacheBust: true,
},
@@ -36,7 +36,7 @@ tape("test xhr request", function(t) {
})
})
t.test("- request is not cache-busted when configured not to be", function(t) {
var requestNoCacheBust = request.bind({
var requestNoCacheBust = sendRequest.bind({
options: {
cacheBust: false,
},