根据Turbolinks 5关于“关注重定向”的文档(https://github.com/turbolinks/turbolinks#following-redirects):
当您访问位置
/one
并且服务器将您重定向到位置时/two
,您希望浏览器的地址栏显示重定向 URL。但是,Turbolinks使用
XMLHttpRequest
发出请求 透明地遵循重定向。 Turbolinks没办法说出来 请求是否导致重定向而没有额外的 来自服务器的合作。
解决方法是:
发送
Turbolinks-Location
标头以响应访问时间 重定向,Turbolinks将取代浏览器的最高历史 具有您提供的价值的条目。Turbolinks Rails引擎会自动为使用
redirect_to
帮助程序重定向的非GET XHR请求执行此优化。
我非常有兴趣在我的Django(1.11)项目中使用Turbolinks,我想知道是否有人能指出我正确的方向如何创建一个新的Django redirect()函数或修改现有的函数包括重定向按预期运行所需的Turbolinks-Location标头。我绝对不希望每次进行重定向时都手动设置此标题。
“表格提交后重定向”部分(https://github.com/turbolinks/turbolinks#redirecting-after-a-form-submission)中有类似的条目我还非常感谢您在理解如何实施方面的任何帮助:
如果表单提交导致服务器上的状态更改 影响缓存页面,请考虑清除Turbolinks的缓存
Turbolinks.clearCache()
。Turbolinks Rails引擎自动执行此优化 对于使用
redirect_to
帮助程序重定向的非GET XHR请求。
我确实看到github上有一个“用于Django的Drop-in turbolinks实现”包,但这是来自turbolinks-classic,而源代码没有提到Turbolinks-Location标题所以我确信这不是我的意思我正在寻找。
答案 0 :(得分:5)
我最终发现了如何通过reddit用户指向此项目https://github.com/viewflow/django-material/blob/v2/material/middleware.py中的一小段代码来完成我正在尝试的操作。
我在我的apps目录下将TurbolinksMiddleware类复制到我自己的middleware.py中,并将其列在我的settings.py中
# MIDDLEWARE CONFIGURATION
# --------------------------------------------------------------------------
MIDDLEWARE = [
.
.
.
'apps.middleware.TurbolinksMiddleware',
]
通过在我的html模板中包含turbolinks.js的常规安装步骤,一切似乎都正常工作。
以下是TurbolinksMiddleware类,以防它在上面的链接中不可用:
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
答案 1 :(得分:0)
您提到的django包实现了middleware,负责添加标头。似乎对于旧的turbolinks,标题有不同的名称。您可以编写自己的中间件来支持turbolinks 5。
不是正常提交表格,而是使用XHR提交表格。
你可以用普通的django实现这一点。阅读django CSRF doc - 他们详细解释了什么是必要的。