使用Fetch发送POST请求后,Django HttpResponse无法实现页面跳转
问题:使用Fetch发送POST请求后无法实现页面跳转
我用JavaScript的Fetch API发送POST请求,后端Django能正常接收并打印数据,但无论用reverse还是redirect都没法让页面跳转到显示"HEY"的页面。
前端Fetch代码
function send_dialog() { fetch('dialog', { method: 'POST', body: JSON.stringify({ id_to_dialog }) }) .then(response => response.json()) .then(result => { // Print result console.log(result); }); }
后端Django视图代码
@csrf_exempt def dialog(request): print(request) data = json.loads(request.body) print(data) return HttpResponse("HEY")
核心原因
Fetch是异步AJAX请求,它只会在后台和服务器通信,不会自动触发浏览器的页面跳转。不管后端返回什么内容,前端默认都只会在then回调里处理响应数据,不会主动刷新或跳转页面。
解决方法
方法1:前端手动处理跳转
如果要保留Fetch异步请求的特性,在拿到后端响应后,用JavaScript主动触发页面跳转:
- 修改前端代码的回调逻辑(注意后端返回的是文本,要把
response.json()改成response.text(),避免JSON解析报错):
function send_dialog() { fetch('dialog', { method: 'POST', body: JSON.stringify({ id_to_dialog }) }) .then(response => response.text()) .then(result => { console.log(result); // 直接跳转到目标页面 window.location.href = "/你要跳转的页面路径/"; }); }
- 也可以让后端返回跳转目标URL,前端动态跳转:
后端视图修改:
from django.http import JsonResponse @csrf_exempt def dialog(request): print(request) data = json.loads(request.body) print(data) # 返回跳转地址 return JsonResponse({"redirect_url": "/显示HEY的页面/"})
前端对应修改:
.then(response => response.json()) .then(result => { console.log(result); window.location.href = result.redirect_url; });
方法2:改用传统表单提交(无需Fetch)
如果不需要异步处理,直接用HTML表单提交,后端的redirect会自动生效:
- 前端表单代码:
<form method="POST" action="/dialog/"> {% csrf_token %} <!-- 记得加CSRF令牌,不用再用csrf_exempt --> <input type="hidden" name="id_to_dialog" value="你的ID值"> <button type="submit">发送请求</button> </form>
- 后端视图修改:
from django.shortcuts import redirect def dialog(request): if request.method == "POST": id_to_dialog = request.POST.get("id_to_dialog") print(id_to_dialog) # 直接跳转目标页面 return redirect("/显示HEY的页面/") # GET请求默认返回内容 return HttpResponse("HEY")
额外注意
- 尽量不要用
csrf_exempt,用Fetch时要在请求头里添加CSRF令牌,避免跨站请求伪造错误:
// 先获取CSRF令牌 function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } const csrftoken = getCookie('csrftoken'); // 发送请求时添加请求头 function send_dialog() { fetch('dialog', { method: 'POST', headers: { 'X-CSRFToken': csrftoken, 'Content-Type': 'application/json' }, body: JSON.stringify({ id_to_dialog }) }) .then(response => response.text()) .then(result => { console.log(result); window.location.href = "/目标页面/"; }); }
内容的提问来源于stack exchange,提问作者QuestionMark
相关产品推荐
相关产品推荐

