乐闻世界logo
搜索文章和话题

How to handle redirect for login_required in htmx partial view?

4 个月前提问
4 个月前修改
浏览次数38

1个答案

1

在使用htmx构建动态网站时,可能会遇到需要在部分视图(partial view)中处理用户身份验证的情况。对于受保护的视图,如果用户未登录,通常会希望重定向用户到登录页面。然而,在使用htmx的异步请求中,这种直接重定向的方式可能不会直接有效,因为它会导致整个页面跳转,而不仅仅是部分视图的更新。因此,我们需要一种方法来处理这种情况。

解决方案

在Django等后端框架中,可以通过自定义的中间件或装饰器来处理这种情况。以下是一种可能的实现方式:

1. 自定义装饰器

首先,我们可以创建一个自定义的装饰器,这个装饰器会检查用户是否登录。如果未登录,装饰器将返回一个特定的响应,该响应能够被htmx正确识别并处理。

python
from django.http import JsonResponse from django.contrib.auth.decorators import login_required def login_required_htmx(view_func): def _wrapped_view(request, *args, **kwargs): if not request.user.is_authenticated: # 检查是否是HTMX请求 if request.headers.get('HX-Request'): return JsonResponse({'redirect': '/login'}, status=403) else: return redirect('/login') return view_func(request, *args, **kwargs) return wraps(view_func)(_wrapped_view)

在这个装饰器中,我们首先检查用户是否登录。如果用户未登录,接下来检查请求是否为HTMX请求(通过请求头中的HX-Request判断)。对于HTMX请求,我们返回一个JSON响应,其中包含重定向的URL。对于非HTMX请求,我们使用常规的重定向。

2. 前端处理

在前端,我们需要确保能够处理这个返回的JSON并执行重定向。

html
<script> document.body.addEventListener('htmx:responseError', function(evt) { if (evt.detail.status === 403 && evt.detail.xhr.responseJSON && evt.detail.xhr.responseJSON.redirect) { window.location.href = evt.detail.xhr.responseJSON.redirect; } }); </script>

在这段JavaScript代码中,我们监听htmx:responseError事件,这个事件在响应状态码为4xx或5xx时触发。我们特别检查状态码403和响应JSON中的重定向字段。如果这些条件满足,我们就使用window.location.href进行页面跳转到指定的登录页面。

总结

通过这种方式,我们可以优雅地处理在部分视图中需要用户登录的情况,而不会影响到用户的交互体验。这种方法的优点是后端和前端的逻辑都保持清晰和简洁,同时能够有效地利用htmx的异步能力来构建响应性强的web应用。

2024年7月21日 11:56 回复

你的答案