【问题标题】:Run a function when the browser is closed Django在浏览器关闭时运行一个函数 Django
【发布时间】:2021-03-04 08:30:32
【问题描述】:

根据我所阅读的内容,无法了解用户是否通过 Django 关闭了浏览器或选项卡。理想情况下,我认为关闭浏览器或选项卡应该没有问题,因为用户会自动注销。

但是,我的问题是我已经覆盖了我的注销视图,因此 Django 对与登录用户相关的模型执行了一些功能(例如保存时间戳等)。每当用户通过关闭浏览器注销时,Django 都不会启动这些功能。它会在用户通过“注销”按钮正常注销时运行。

这是我覆盖的注销视图:

def logout(request):
    reset_logged_acc(request) #do something
    auth_logout(request) #custom log-out
    return redirect('home')

我在某处读过我可以执行一些 ajax 请求以及不知道用户是否仍然存在的内容。我认为这是可能的,但如果没有任何结果,我会将此选项作为最后的手段。

有没有其他方法可以实现这一点?

【问题讨论】:

  • Django 无法知道有人关闭了浏览器,因为浏览器并没有为此发送请求。
  • 我相信这个问题的答案是使用客户端代码可以做到的最好的。 stackoverflow.com/questions/24865561/…
  • 这是一个jQuery解决方案,每分钟左右使用一次ajax请求stackoverflow.com/questions/4096955/…
  • 感谢@FSDford 将调查这些 SO 答案
  • @FSDford 考虑到如果我选择使用 ajax 路由,我将如何在 Django 中实现它?我在客户端发送 ajax 请求时没有问题,但我不知道如果 Django 没有收到任何请求,我如何识别它。 Django 中是否有任何计时器或其他任何东西,所以我可以每隔 n 秒检查一次?

标签: python jquery django ajax django-views


【解决方案1】:

找到了解决这个问题的方法,虽然不是很漂亮。

基本上,我只是创建了一个request.session['window_num'],它表示从 Django 生成的数字窗口。

所以这意味着对于每个 GET 请求,Django 都会通过add_window(request) 增加会话变量。

为了处理页面的删除或关闭,我只是使用了 Javascript 中 $(window).on('unload', function() {}); 函数包围的 navigator.sendBeacon 函数向 Django 发送请求。 Django 然后通过delete_window(request) 递减会话变量。

然后我在函数关闭之前添加了一条 if 语句,以检查会话变量是否变为 0。如果变为 0,它将调用我覆盖的注销函数。

我承认这不是最好的代码,所以我仍然愿意接受任何改进或替代方案。之所以发布这个是因为它有效。

每隔 n 秒尝试一次 ajax 请求,但无法在 Django 中实现。

这些是以下代码:

navigator.sendBeacon

$(window).on('unload', function() {
      var data = new FormData();        
      data.append('csrfmiddlewaretoken', '{{csrf_token}}');
      navigator.sendBeacon("{% url 'delete_window' %}",data);
  });

views.py

@csrf_exempt
def delete_window(request):    
    window_num = int(request.session['window_num'])
    window_num -= 1
    request.session['window_num'] = str( window_num )
    
    if int( request.session['window_num'] ) == 0:
        if request.user.is_authenticated:
            logout(request) #calls out overridden log-out function          

    data = {}
    return JsonResponse(data)

def add_window(request):
    if 'window_num' in list(request.session.keys()): #there are existing pages
        window_num = int(request.session['window_num'])
        window_num += 1 
        request.session['window_num'] = str( window_num )

    else: #first time load
        request.session['window_num'] = "1"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-24
    • 2014-05-16
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多