- Pass the AJAX referer for all AJAX requests.

- Switch to synchronous requests.
- All location changes go through the setLocation method.
- Switch to using history.pushState.
- AJAX middleware inserts AJAX referer as the request HTTP_REFERER.

Signed-off-by: Eric Riggs <ericriggs42@gmail.com>
This commit is contained in:
Eric Riggs
2018-03-06 23:19:34 -04:00
committed by Roberto Rosario
parent f3f4dcd84a
commit 3be28131c9
2 changed files with 36 additions and 21 deletions

View File

@@ -14,13 +14,14 @@ var PartialNavigation = function (parameters) {
this.initialURL = parameters.initialURL || null; this.initialURL = parameters.initialURL || null;
this.excludeAnchorClasses = parameters.excludeAnchorClasses || []; this.excludeAnchorClasses = parameters.excludeAnchorClasses || [];
this.lastLocation = null;
if (!this.initialURL) { if (!this.initialURL) {
alert('Need to setup initialURL'); alert('Need to setup initialURL');
} }
this.setupAjaxAnchors(); this.setupAjaxAnchors();
this.setupHashLocation(); this.setupAjaxNavigation();
this.setupAjaxForm(); this.setupAjaxForm();
} }
@@ -44,19 +45,20 @@ PartialNavigation.prototype.loadAjaxContent = function (url) {
url = this.filterLocation(url); url = this.filterLocation(url);
console.log('>> loadAjaxContent.filterLocation.url: ' + url); console.log('>> loadAjaxContent.filterLocation.url: ' + url);
$.ajax({ $.ajax({
async: true, async: false,
mimeType: 'text/html; charset=utf-8', // ! Need set mimeType only when run from local file mimeType: 'text/html; charset=utf-8', // ! Need set mimeType only when run from local file
url: url, url: url,
type: 'GET', type: 'GET',
success: function(data, textStatus, response){ success: function (data, textStatus, response){
if (response.status == 278) { if (response.status == 278) {
console.log('>> loadAjaxContent.ajax: got HTTP278'); console.log('>> loadAjaxContent.ajax: got HTTP278');
var newLocation = response.getResponseHeader('Location'); var newLocation = response.getResponseHeader('Location');
console.log('>> loadAjaxContent.ajax.newLocation: ' + newLocation); console.log('>> loadAjaxContent.ajax.newLocation: ' + newLocation);
app.setLocation(newLocation); app.setLocation(newLocation);
app.lastLocation = newLocation;
} else { } else {
app.lastLocation = url;
if (response.getResponseHeader('Content-Disposition')) { if (response.getResponseHeader('Content-Disposition')) {
window.location = this.url; window.location = this.url;
} else { } else {
@@ -64,7 +66,7 @@ PartialNavigation.prototype.loadAjaxContent = function (url) {
} }
} }
}, },
error: function(jqXHR, textStatus, errorThrown){ error: function (jqXHR, textStatus, errorThrown){
app.processAjaxRequestError(jqXHR); app.processAjaxRequestError(jqXHR);
}, },
dataType: 'html', dataType: 'html',
@@ -105,21 +107,22 @@ PartialNavigation.prototype.processAjaxRequestError = function (jqXHR) {
$('#modal-server-error').modal('show') $('#modal-server-error').modal('show')
} }
PartialNavigation.prototype.setLocation = function (newLocation) { PartialNavigation.prototype.setLocation = function (newLocation, pushState) {
console.log('>> setLocation.newLocation: ' + newLocation); console.log('>> setLocation.newLocation: ' + newLocation);
console.log('>> setLocation.location: ' + location); console.log('>> setLocation.location: ' + location);
newLocation = this.filterLocation(newLocation); newLocation = this.filterLocation(newLocation);
var currentLocationPath = new URI(location).fragment(); if (typeof pushState === 'undefined') {
var newLocationPath = new URI(newLocation).path(); pushState = true;
console.log(currentLocationPath);
console.log(newLocationPath);
if (currentLocationPath === newLocationPath) {
// New location same as old, force a reload
this.loadAjaxContent(newLocation);
} }
window.location.hash = newLocation;
var currentLocation = new URI(location);
currentLocation.fragment(newLocation);
if (pushState) {
history.pushState({}, '', currentLocation);
}
this.loadAjaxContent(newLocation);
} }
PartialNavigation.prototype.setupAjaxAnchors = function () { PartialNavigation.prototype.setupAjaxAnchors = function () {
@@ -133,10 +136,9 @@ PartialNavigation.prototype.setupAjaxForm = function () {
var app = this; var app = this;
$('form').ajaxForm({ $('form').ajaxForm({
async: true, async: false,
beforeSubmit: function(arr, $form, options) { beforeSubmit: function(arr, $form, options) {
console.log('>> ajaxForm.beforeSubmit.$form.target: ' + $form.attr('action')); console.log('>> ajaxForm.beforeSubmit.$form.target: ' + $form.attr('action'));
var uri = new URI(location); var uri = new URI(location);
var uriFragment = uri.fragment(); var uriFragment = uri.fragment();
console.log('>>ajaxForm.$form.target.uriFragment:' + uriFragment); console.log('>>ajaxForm.$form.target.uriFragment:' + uriFragment);
@@ -170,7 +172,6 @@ PartialNavigation.prototype.setupAjaxForm = function () {
var url = uriFragment || currentUriFragment; var url = uriFragment || currentUriFragment;
app.setLocation(newLocation); app.setLocation(newLocation);
} else { } else {
console.log('>>ajaxForm.success'); console.log('>>ajaxForm.success');
$('#ajax-content').html(data); $('#ajax-content').html(data);
@@ -179,16 +180,16 @@ PartialNavigation.prototype.setupAjaxForm = function () {
}); });
} }
PartialNavigation.prototype.setupHashLocation = function () { PartialNavigation.prototype.setupAjaxNavigation = function () {
var app = this; var app = this;
// Load ajax content when the hash changes // Load ajax content when the hash changes
if (window.history && window.history.pushState) { if (window.history && window.history.pushState) {
$(window).on('popstate', function() { $(window).on('popstate', function() {
console.log('>> setupHashLocation.location: ' + location); console.log('>> setupHashLocation.popstate.location: ' + location);
var uri = new URI(location); var uri = new URI(location);
var uriFragment = uri.fragment(); var uriFragment = uri.fragment();
app.loadAjaxContent(uriFragment); app.setLocation(uriFragment, false);
}); });
} }
@@ -200,4 +201,10 @@ PartialNavigation.prototype.setupHashLocation = function () {
} else { } else {
this.setLocation('/'); this.setLocation('/');
} }
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
jqXHR.setRequestHeader('X-Alt-Referer', app.lastLocation);
},
});
} }

View File

@@ -5,6 +5,14 @@ from django.http import HttpResponseRedirect
class AjaxRedirect(object): class AjaxRedirect(object):
def process_request(self, request):
ajax_referer = request.META.get('HTTP_X_ALT_REFERER')
if ajax_referer:
request.META['HTTP_REFERER'] = ajax_referer
return None
def process_response(self, request, response): def process_response(self, request, response):
if request.is_ajax(): if request.is_ajax():
if type(response) == HttpResponseRedirect: if type(response) == HttpResponseRedirect: