From 3be28131c9e8de12c664e90521f7ad391e8bbf13 Mon Sep 17 00:00:00 2001 From: Eric Riggs Date: Tue, 6 Mar 2018 23:19:34 -0400 Subject: [PATCH] - 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 --- .../appearance/js/partial_navigation.js | 49 +++++++++++-------- mayan/apps/common/middleware/ajax_redirect.py | 8 +++ 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/mayan/apps/appearance/static/appearance/js/partial_navigation.js b/mayan/apps/appearance/static/appearance/js/partial_navigation.js index 062bceaae8..4a0e02270e 100644 --- a/mayan/apps/appearance/static/appearance/js/partial_navigation.js +++ b/mayan/apps/appearance/static/appearance/js/partial_navigation.js @@ -14,13 +14,14 @@ var PartialNavigation = function (parameters) { this.initialURL = parameters.initialURL || null; this.excludeAnchorClasses = parameters.excludeAnchorClasses || []; + this.lastLocation = null; if (!this.initialURL) { alert('Need to setup initialURL'); } this.setupAjaxAnchors(); - this.setupHashLocation(); + this.setupAjaxNavigation(); this.setupAjaxForm(); } @@ -44,19 +45,20 @@ PartialNavigation.prototype.loadAjaxContent = function (url) { url = this.filterLocation(url); console.log('>> loadAjaxContent.filterLocation.url: ' + url); $.ajax({ - async: true, + async: false, mimeType: 'text/html; charset=utf-8', // ! Need set mimeType only when run from local file url: url, type: 'GET', - success: function(data, textStatus, response){ + success: function (data, textStatus, response){ if (response.status == 278) { console.log('>> loadAjaxContent.ajax: got HTTP278'); var newLocation = response.getResponseHeader('Location'); console.log('>> loadAjaxContent.ajax.newLocation: ' + newLocation); - app.setLocation(newLocation); + app.lastLocation = newLocation; } else { + app.lastLocation = url; if (response.getResponseHeader('Content-Disposition')) { window.location = this.url; } else { @@ -64,7 +66,7 @@ PartialNavigation.prototype.loadAjaxContent = function (url) { } } }, - error: function(jqXHR, textStatus, errorThrown){ + error: function (jqXHR, textStatus, errorThrown){ app.processAjaxRequestError(jqXHR); }, dataType: 'html', @@ -105,21 +107,22 @@ PartialNavigation.prototype.processAjaxRequestError = function (jqXHR) { $('#modal-server-error').modal('show') } -PartialNavigation.prototype.setLocation = function (newLocation) { +PartialNavigation.prototype.setLocation = function (newLocation, pushState) { console.log('>> setLocation.newLocation: ' + newLocation); console.log('>> setLocation.location: ' + location); newLocation = this.filterLocation(newLocation); - var currentLocationPath = new URI(location).fragment(); - var newLocationPath = new URI(newLocation).path(); - - console.log(currentLocationPath); - console.log(newLocationPath); - if (currentLocationPath === newLocationPath) { - // New location same as old, force a reload - this.loadAjaxContent(newLocation); + if (typeof pushState === 'undefined') { + pushState = true; } - window.location.hash = newLocation; + + var currentLocation = new URI(location); + currentLocation.fragment(newLocation); + + if (pushState) { + history.pushState({}, '', currentLocation); + } + this.loadAjaxContent(newLocation); } PartialNavigation.prototype.setupAjaxAnchors = function () { @@ -133,10 +136,9 @@ PartialNavigation.prototype.setupAjaxForm = function () { var app = this; $('form').ajaxForm({ - async: true, + async: false, beforeSubmit: function(arr, $form, options) { console.log('>> ajaxForm.beforeSubmit.$form.target: ' + $form.attr('action')); - var uri = new URI(location); var uriFragment = uri.fragment(); console.log('>>ajaxForm.$form.target.uriFragment:' + uriFragment); @@ -170,7 +172,6 @@ PartialNavigation.prototype.setupAjaxForm = function () { var url = uriFragment || currentUriFragment; app.setLocation(newLocation); - } else { console.log('>>ajaxForm.success'); $('#ajax-content').html(data); @@ -179,16 +180,16 @@ PartialNavigation.prototype.setupAjaxForm = function () { }); } -PartialNavigation.prototype.setupHashLocation = function () { +PartialNavigation.prototype.setupAjaxNavigation = function () { var app = this; // Load ajax content when the hash changes if (window.history && window.history.pushState) { $(window).on('popstate', function() { - console.log('>> setupHashLocation.location: ' + location); + console.log('>> setupHashLocation.popstate.location: ' + location); var uri = new URI(location); var uriFragment = uri.fragment(); - app.loadAjaxContent(uriFragment); + app.setLocation(uriFragment, false); }); } @@ -200,4 +201,10 @@ PartialNavigation.prototype.setupHashLocation = function () { } else { this.setLocation('/'); } + + $.ajaxSetup({ + beforeSend: function (jqXHR, settings) { + jqXHR.setRequestHeader('X-Alt-Referer', app.lastLocation); + }, + }); } diff --git a/mayan/apps/common/middleware/ajax_redirect.py b/mayan/apps/common/middleware/ajax_redirect.py index 805ced8478..24166d685a 100644 --- a/mayan/apps/common/middleware/ajax_redirect.py +++ b/mayan/apps/common/middleware/ajax_redirect.py @@ -5,6 +5,14 @@ from django.http import HttpResponseRedirect 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): if request.is_ajax(): if type(response) == HttpResponseRedirect: