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

使用fetch() API请求Django视图后,重定向丢失messages消息如何解决?

问题原因

fetch API默认会自动跟随重定向,导致在你调用location.replace()之前,浏览器已经悄悄向重定向目标URL发送了GET请求。Django的messages框架会在这次请求中读取并清除session里的消息,所以当你手动跳转时,session中已经没有消息可显示了。

解决方案

方案一:阻止fetch自动跟随重定向(推荐)

修改JavaScript中的请求配置,添加redirect: "manual"来禁止自动跟随,然后手动获取重定向URL再跳转:

修改后的JavaScript代码

var csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
const headers = new Headers();
headers.append("X-CSRFToken", csrftoken);

const form = new FormData();
form.append("pproject", "{{ project.id }}");

const ops = {
    method: "POST",
    headers: headers,
    body: form,
    credentials: "same-origin",
    redirect: "manual" // 新增:阻止自动跟随重定向
};

const req = new Request("{% url 'project_add' %}");

fetch(req, ops)
.then((response) => {
    // 处理3xx重定向状态码
    if (response.status >= 300 && response.status < 400) {
        const redirectUrl = response.headers.get('Location');
        window.location.replace(redirectUrl);
    } else if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status}`);
    } else {
        return response.json();
    }
})

这样fetch不会提前访问重定向目标,只有当你手动调用location.replace()时才会发起第一次请求,messages会被正确读取并显示。

方案二:视图返回JSON携带消息和重定向URL

如果需要更灵活的前端控制,可以修改Django视图,返回包含消息和重定向地址的JSON,前端存储消息后再跳转:

修改后的Django视图代码

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

def add(request):
    if request.method != 'POST':
        return HttpResponse("not post")

    pproject = request.POST['pproject']
    print("pproject:", pproject)
    
    message_content = "Test."
    # 返回JSON数据
    return JsonResponse({
        'redirect_url': reverse('project_detail'),
        'message': message_content,
        'message_level': 'INFO'
    })

修改后的前端JavaScript代码

// (前面的请求配置不变)
fetch(req, ops)
.then((response) => {
    if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status}`);
    } else {
        return response.json();
    }
})
.then((data) => {
    // 将消息存入sessionStorage
    sessionStorage.setItem('django_message', JSON.stringify({
        text: data.message,
        level: data.message_level
    }));
    // 跳转到目标页面
    window.location.replace(data.redirect_url);
})

目标页面添加消息显示逻辑

在目标页面的模板中添加JavaScript,读取存储的消息并显示:

<script>
document.addEventListener('DOMContentLoaded', () => {
    const storedMsg = sessionStorage.getItem('django_message');
    if (storedMsg) {
        const { text, level } = JSON.parse(storedMsg);
        // 创建符合Django消息样式的元素
        const msgElement = document.createElement('div');
        msgElement.className = `alert alert-${level.toLowerCase()}`;
        msgElement.textContent = text;
        // 插入到页面的消息容器(假设容器id为messages)
        const msgContainer = document.getElementById('messages');
        if (msgContainer) msgContainer.appendChild(msgElement);
        // 清除存储的消息
        sessionStorage.removeItem('django_message');
    }
});
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 11:42:18