You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django Web应用中实现类似WhatsApp Web的周期性更新动态二维码的方案咨询

在Django Web应用中实现类似WhatsApp Web的周期性更新动态二维码的方案咨询

嘿,这个需求我之前帮朋友处理过,其实核心就是结合后端生成带动态内容的二维码和前端定时刷新机制来实现,跟WhatsApp Web的逻辑差不多——每段时间生成一个新的临时会话标识,把它做成二维码,前端定时拉取新的二维码展示。下面给你分步骤拆解可行的方案:

一、后端Django实现动态二维码生成

首先需要一个能生成二维码的库,最常用的是qrcode,也可以用封装更友好的django-qr-code。这里先给你写最基础的原生实现:

1. 安装依赖

先装二维码生成库:

pip install qrcode[pil]

2. 编写动态二维码视图

关键是要禁止浏览器缓存,确保每次请求都能拿到新的二维码。视图里可以生成动态内容(比如临时会话ID、一次性token,对应WhatsApp的登录会话逻辑),然后把内容转成二维码图片返回:

# views.py
import qrcode
import random
from io import BytesIO
from django.http import HttpResponse
from django.views.decorators.cache import never_cache

@never_cache  # 必须加!避免浏览器缓存旧二维码
def dynamic_login_qr(request):
    # 这里替换成你的业务逻辑:比如生成用户专属的临时登录token
    # 示例:生成和当前会话绑定的随机临时标识
    temp_session_id = f"temp-login-{request.session.session_key}-{random.randint(10000, 99999)}"
    
    # 生成二维码
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=8,
        border=2,
    )
    qr.add_data(temp_session_id)
    qr.make(fit=True)
    
    # 将二维码转成字节流返回给前端
    img_buffer = BytesIO()
    qr.make_image(fill_color="#000", back_color="#fff").save(img_buffer, format="PNG")
    img_buffer.seek(0)
    
    return HttpResponse(img_buffer, content_type="image/png")

3. 配置路由

在项目的urls.py里添加二维码接口的路由:

# urls.py
from django.urls import path
from .views import dynamic_login_qr

urlpatterns = [
    # 其他路由...
    path("login/qr/", dynamic_login_qr, name="dynamic_login_qr"),
]

二、前端实现定时刷新二维码

前端的核心是每隔10秒请求一次新的二维码,这里要注意给URL加时间戳参数,避免浏览器因为URL相同而返回缓存的旧图片:

<!-- templates/login_qr.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>扫码登录</title>
</head>
<body>
    <div class="qr-container">
        <h3>扫码登录你的账号</h3>
        <img id="dynamic-qr-img" src="{% url 'dynamic_login_qr' %}" alt="动态登录二维码">
        <p>二维码每10秒自动刷新</p>
    </div>

    <script>
        // 定时刷新逻辑:每10秒更新一次图片src
        const qrImg = document.getElementById('dynamic-qr-img');
        setInterval(() => {
            // 加时间戳参数,确保每次请求的URL唯一,绕过缓存
            const timestamp = new Date().getTime();
            qrImg.src = "{% url 'dynamic_login_qr' %}?t=" + timestamp;
        }, 10000); // 10000毫秒 = 10秒
    </script>
</body>
</html>

三、进阶优化建议

  1. 用WebSocket替代定时轮询:如果你的项目需要更实时的状态同步(比如扫码成功后立即停止刷新并跳转),可以结合Django Channels实现WebSocket推送,后端检测到扫码成功后主动通知前端,比定时轮询更高效。
  2. 使用封装好的Django二维码库:如果你不想自己写生成逻辑,可以用django-qr-code,它提供了模板标签和视图,能快速生成二维码,只需要在模板里调用标签,再配合前端定时刷新即可。
  3. 业务逻辑绑定:实际项目中,二维码里的动态内容要和后端的会话/用户状态绑定,比如生成的临时token要存在Redis里,设置10秒过期,扫码后验证token有效性,完成登录流程。

四、常见坑点提醒

  • 一定要加@never_cache装饰器:否则浏览器会缓存第一次请求的二维码,后续刷新都是旧图。
  • 动态内容要唯一且时效性强:像WhatsApp的二维码里是临时会话ID,过期就失效,避免重复使用带来安全问题。
  • 图片尺寸优化:生成二维码时调整box_size和border参数,确保扫码清晰,同时不要太大影响加载速度。

备注:内容来源于stack exchange,提问作者Muhammadoufi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 09:45:28