Django中Ajax POST请求失效求助:点击提交按钮页面仍刷新
解决Django Ajax提交评论页面刷新的问题
作为刚接触Django和Ajax的新手,遇到这种情况太正常了,咱们一步步排查解决:
一、先阻止表单的默认提交行为
这是最常见的问题!点击提交按钮时,浏览器会默认触发表单的submit事件跳转页面,必须先把这个默认行为干掉。
假设你的HTML表单结构是这样的:
<form id="comment-form" method="post" action="{% url 'news:submit_comment' news_pk %}"> {% csrf_token %} <textarea name="content" placeholder="写下你的评论..."></textarea> <button type="submit">提交评论</button> </form>
用jQuery实现Ajax的写法:
// 确保DOM加载完成后再执行代码 $(document).ready(function() { $('#comment-form').on('submit', function(e) { // 核心:阻止表单默认提交行为 e.preventDefault(); // 序列化表单数据(自动包含CSRF令牌) var formData = $(this).serialize(); var submitUrl = $(this).attr('action'); $.ajax({ type: 'POST', url: submitUrl, data: formData, success: function(response) { // 成功后的操作:比如把新评论插入页面顶部 $('#comment-list').prepend(` <div class="comment-item"> <p>${response.content}</p> <span>by ${response.author} ${response.add_time}</span> </div> `); // 清空评论输入框 $('#comment-form textarea').val(''); }, error: function() { alert('评论提交失败,请稍后重试'); } }); }); });
用原生JS实现的写法:
document.addEventListener('DOMContentLoaded', function() { const commentForm = document.getElementById('comment-form'); commentForm.addEventListener('submit', function(e) { e.preventDefault(); const formData = new FormData(this); const submitUrl = this.action; fetch(submitUrl, { method: 'POST', headers: { // 告诉Django这是Ajax请求 'X-Requested-With': 'XMLHttpRequest' }, body: formData }) .then(res => res.json()) .then(data => { if (data.status === 'success') { const commentList = document.getElementById('comment-list'); const newComment = document.createElement('div'); newComment.className = 'comment-item'; newComment.innerHTML = `<p>${data.content}</p><span>by ${data.author} ${data.add_time}</span>`; commentList.prepend(newComment); commentForm.querySelector('textarea').value = ''; } else { alert(data.message); } }) .catch(() => alert('提交出错啦')); }); });
二、后端视图要适配Ajax请求
你的视图需要判断是否为Ajax请求,并且返回JSON数据(不能返回页面模板),示例如下:
from django.http import JsonResponse from django.shortcuts import get_object_or_404 from .models import News, Comment def submit_comment(request, news_pk): news = get_object_or_404(News, id=news_pk) # 判断是否为Ajax请求(Django3.1+推荐用这个方式) if request.method == 'POST' and request.headers.get('X-Requested-With') == 'XMLHttpRequest': content = request.POST.get('content', '').strip() if not content: return JsonResponse({'status': 'error', 'message': '评论内容不能为空'}) # 创建评论(这里假设用户已登录,根据你的实际逻辑调整) comment = Comment.objects.create( news=news, content=content, author=request.user ) # 返回前端需要的JSON数据 return JsonResponse({ 'status': 'success', 'content': comment.content, 'author': comment.author.username, 'add_time': comment.add_time.strftime('%Y-%m-%d %H:%M') }) # 非Ajax请求直接返回错误 return JsonResponse({'status': 'error', 'message': '非法请求'})
三、关键注意事项
- CSRF令牌处理:表单里一定要加
{% csrf_token %},不管用jQuery的serialize()还是原生的FormData,都会自动带上这个令牌,避免Django的CSRF拦截。 - JS加载时机:确保你的JavaScript代码放在
</body>标签前,或者用$(document).ready()/DOMContentLoaded包裹,不然DOM还没加载完,找不到表单元素,代码就不会生效。 - 排查控制台错误:按F12打开浏览器开发者工具,切换到Console标签,看看有没有JS报错(比如找不到jQuery、找不到表单元素),这些错误会直接导致Ajax代码不执行,表单就会默认提交刷新页面。
按照上面的步骤一步步检查,应该就能解决页面刷新的问题啦!
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

