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

Django中XMLHttpRequest请求后带消息重定向失效及Cookie问题解决

问题分析与解决方案

核心问题

  1. 重定向不生效:你用XMLHttpRequest发起异步POST请求,后端返回的redirect响应只会被XHR对象处理(自动请求重定向后的URL),但不会触发浏览器页面跳转——这是XHR的特性,它不会主动刷新或跳转当前页面。
  2. messages Cookie过期:旧的messages Cookie已过期,Django尝试设置新的messages Cookie时,浏览器拒绝接收过期的旧Cookie,或者Cookie的有效期配置存在问题。

解决方案

1. 调整后端逻辑:返回JSON而非直接重定向

后端不再直接返回redirect,而是返回包含跳转地址和消息的JSON数据,同时处理过期Cookie的删除:

from django.http import JsonResponse
from django.urls import reverse
from django.contrib.messages import get_messages

def newSeq(request):
    if request.method == "POST":
        # 处理过期的messages Cookie(如果存在)
        response_data = {
            'redirect_url': reverse('newSeq'),
            'message': 'Ricevuto'
        }
        response = JsonResponse(response_data)
        
        if 'messages' in request.COOKIES:
            # 删除过期的messages Cookie
            response.delete_cookie('messages')
        
        return response
    
    # GET请求时,正常渲染页面并传递messages
    messages_list = [m.message for m in get_messages(request)]
    return render(
        request,
        'dashboard/newSeq.html',
        {
            'messages': messages_list
        }
    )

2. 修改前端代码:处理响应并手动跳转

给XMLHttpRequest添加onload事件,接收后端返回的JSON数据,完成页面跳转并按需显示消息:

var xmlhttp = new XMLHttpRequest();
var theUrl = "newSeq";
xmlhttp.open("POST", theUrl);
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xmlhttp.setRequestHeader("X-CSRFToken", csrftoken);

// 添加响应处理逻辑
xmlhttp.onload = function() {
    if (this.status >= 200 && this.status < 300) {
        const response = JSON.parse(this.responseText);
        // 手动跳转到目标页面
        window.location.href = response.redirect_url;
        // 可选:跳转前显示消息
        alert(response.message);
    }
};

xmlhttp.send(JSON.stringify(my_json));

3. 可选:保留Django Messages框架的方案

如果想继续使用Django的messages框架,可让后端在XHR请求中重置有效Cookie,前端跳转后在页面渲染messages:

from django.shortcuts import redirect
from django.http import JsonResponse
from django.contrib.messages import get_messages

def newSeq(request):
    if request.method == "POST":
        messages.success(request, "Ricevuto")
        redirect_response = redirect("newSeq")
        
        # 删除过期的messages Cookie(如果存在)
        if 'messages' in request.COOKIES:
            redirect_response.delete_cookie('messages')
        
        # 返回跳转地址给前端
        return JsonResponse({
            'redirect_url': redirect_response.url
        })
    
    messages_list = [m.message for m in get_messages(request)]
    return render(
        request,
        'dashboard/newSeq.html',
        {
            'messages': messages_list
        }
    )

同时在前端模板中添加messages渲染逻辑:

{% if messages %}
    {% for message in messages %}
        <div class="alert alert-success">{{ message }}</div>
    {% endfor %}
{% endif %}

关键说明

  • 删除特定Cookie:Django的所有HttpResponse子类(包括JsonResponse、redirect返回的响应)都支持delete_cookie()方法,传入Cookie名称即可删除对应Cookie,比如response.delete_cookie('messages')。
  • XHR请求的重定向限制:异步请求不会触发页面跳转,必须通过前端window.location.href手动实现页面跳转。

内容的提问来源于stack exchange,提问作者NicoCaldo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:20:15