According to the Turbolinks 5 documentation for "Following Redirects" (https://github.com/turbolinks/turbolinks#following-redirects):
When you visit location
/one
and the server redirects you to location/two
, you expect the browser’s address bar to display the redirected URL.However, Turbolinks makes requests using
XMLHttpRequest
, which transparently follows redirects. There’s no way for Turbolinks to tell whether a request resulted in a redirect without additional cooperation from the server.
And the solution for this is to:
send the
Turbolinks-Location
header in response to a visit that was redirected, and Turbolinks will replace the browser’s topmost history entry with the value you provide.The Turbolinks Rails engine performs this optimization automatically for non-GET XHR requests that redirect with the
redirect_to
helper.
I have a great interest in using Turbolinks on my Django (1.11) project and I'm wondering if anyone could point me in the right direction of how to create a new Django redirect() function or modify the existing one to always include the Turbolinks-Location header that is needed for redirects to function as expected. I definitely do not want to be manually setting this header every time I do a redirect.
There is a similar entry in the 'Redirecting After a Form Submission' section (https://github.com/turbolinks/turbolinks#redirecting-after-a-form-submission) I would also appreciate any help in understanding how to implement:
If form submission results in a state change on the server that affects cached pages, consider clearing Turbolinks’ cache with
Turbolinks.clearCache()
.The Turbolinks Rails engine performs this optimization automatically for non-GET XHR requests that redirect with the
redirect_to
helper.
I did see there is a "Drop-in turbolinks implementation for Django" package on github but this is forked from turbolinks-classic and sourcecode has no mentions of the Turbolinks-Location header so I am sure this is not what I'm looking for.
I did end up discovering how to do exactly what I was attempting by being pointed to a blob of code in this project https://github.com/viewflow/django-material/blob/v2/material/middleware.py by a reddit user.
I copied the TurbolinksMiddleware class into my own middleware.py under my apps directory and listed it in my settings.py as such
# MIDDLEWARE CONFIGURATION
# --------------------------------------------------------------------------
MIDDLEWARE = [
.
.
.
'apps.middleware.TurbolinksMiddleware',
]
With the regular installation step of including the turbolinks.js in my html template, everything appeared to be working correctly.
Here is the TurbolinksMiddleware class in case it should not be available at the link above:
class TurbolinksMiddleware(object):
"""
Send the `Turbolinks-Location` header in response to a visit that was redirected,
and Turbolinks will replace the browser’s topmost history entry .
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
is_turbolinks = request.META.get('HTTP_TURBOLINKS_REFERRER')
is_response_redirect = response.has_header('Location')
if is_turbolinks:
if is_response_redirect:
location = response['Location']
prev_location = request.session.pop('_turbolinks_redirect_to', None)
if prev_location is not None:
# relative subsequent redirect
if location.startswith('.'):
location = prev_location.split('?')[0] + location
request.session['_turbolinks_redirect_to'] = location
else:
if request.session.get('_turbolinks_redirect_to'):
location = request.session.pop('_turbolinks_redirect_to')
response['Turbolinks-Location'] = location
return response
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With