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

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': '非法请求'})

三、关键注意事项

  1. CSRF令牌处理:表单里一定要加{% csrf_token %},不管用jQuery的serialize()还是原生的FormData,都会自动带上这个令牌,避免Django的CSRF拦截。
  2. JS加载时机:确保你的JavaScript代码放在</body>标签前,或者用$(document).ready()/DOMContentLoaded包裹,不然DOM还没加载完,找不到表单元素,代码就不会生效。
  3. 排查控制台错误:按F12打开浏览器开发者工具,切换到Console标签,看看有没有JS报错(比如找不到jQuery、找不到表单元素),这些错误会直接导致Ajax代码不执行,表单就会默认提交刷新页面。

按照上面的步骤一步步检查,应该就能解决页面刷新的问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 07:04:25