Django返回HttpResponseRedirect后浏览器未重定向问题解决
问题描述
前端通过AJAX提交授权表单,验证成功后Django后端返回HttpResponseRedirect(指向name为'main'的路由),但浏览器未执行重定向,控制台仅显示目标页面的HTML代码,Django日志显示GET请求返回200状态码。尝试使用redirect、HttpResponseRedirect均无效,寻求该问题的原因及解决办法。
原因分析
AJAX属于异步请求,浏览器不会自动响应AJAX返回的重定向指令。后端返回的HttpResponseRedirect本质是返回302状态码和目标URL的响应头,但AJAX只会接收响应内容(即目标页面的HTML),不会触发页面跳转。
解决办法
方案1:后端返回JSON,前端主动跳转
修改后端逻辑,验证成功后返回包含跳转URL的JSON数据,由前端JS处理跳转动作。
修改后端代码
from django.http import JsonResponse from django.urls import reverse from django.core.exceptions import ObjectDoesNotExist def auth(request): if request.method == 'GET': return render(request, 'Study/auth.html') elif request.method == 'POST': try: data = dict_from_raw_data(request.body) user = User.get_user(data['login'], data['password']) request.session['cookie'] = user.cookie # 返回跳转地址的JSON响应 return JsonResponse({'redirect_url': reverse('main')}) except ObjectDoesNotExist: return JsonResponse(USER_DOES_NOT_EXIST)
修改前端代码
在AJAX请求的回调中处理后端返回的跳转指令:
function getCookie(name) { let cookie_value; let cookies = document.cookie.split(';'); for (let idx = 0; idx < cookies.length; idx++){ if (cookies[idx].split('=')[0].trim() == name){ cookie_value = cookies[idx].split('=')[1].trim(); return cookie_value; } } } function send(data, csrftoken) { let request = new XMLHttpRequest(); request.open('POST', document.location, false); request.setRequestHeader('X-CSRFToken', csrftoken); request.setRequestHeader('Content-Type', 'application/json'); // 新增,明确请求格式 data = JSON.stringify(data); // 监听请求完成事件 request.onload = function() { if (request.status === 200) { const response = JSON.parse(request.responseText); if (response.redirect_url) { // 触发页面跳转 window.location.href = response.redirect_url; } } }; request.send(data); } let button = document.getElementById('button'); let csrftoken = getCookie('csrftoken'); button.onclick = () => { let form = document.getElementById('auth'); let data = {}; for (let i = 0; i < form.elements.length; i++){ data[form.elements[i].name] = form.elements[i].value; } send(data, csrftoken); }
方案2:直接提交表单,弃用AJAX
如果不需要异步提交的交互需求,直接使用表单默认提交方式,后端的HttpResponseRedirect就能正常触发浏览器跳转。
修改前端代码
去掉AJAX逻辑,让按钮触发表单提交:
let button = document.getElementById('button'); button.onclick = () => { let form = document.getElementById('auth'); form.submit(); };
同时确保表单标签配置正确:
<form id="auth" action="{% url 'auth' %}" method="POST"> {% csrf_token %} <!-- 你的表单输入元素 --> </form>
内容的提问来源于stack exchange,提问作者Полянин Алексей
相关产品推荐
相关产品推荐

