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

Django中表单提交按钮无法通过JavaScript触发提交的问题

问题:提交邮件按钮无响应,无法触发submit_mail函数

我在Django项目中实现邮件功能,使用以下HTML和JavaScript代码,但点击提交按钮后没有任何反应,浏览器控制台也未显示错误,无法触发submit_mail函数。

HTML代码

{% extends "mail/layout.html" %}
{% load static %}

{% block body %}
    <h2>{{ request.user.email }}</h2>

    <button class="btn btn-sm btn-outline-primary" id="inbox">Inbox</button>
    <button class="btn btn-sm btn-outline-primary" id="compose">Compose</button>
    <button class="btn btn-sm btn-outline-primary" id="sent">Sent</button>
    <button class="btn btn-sm btn-outline-primary" id="archived">Archived</button>
    <a class="btn btn-sm btn-outline-primary" href="{% url 'logout' %}">Log Out</a>
    <hr>

    <div id="emails-view">
    </div>

    <div id="compose-view">
        <h3>New Email</h3>
        <form id="compose-form">
            <div class="form-group">
                From: <input disabled class="form-control" value="{{ request.user.email }}">
            </div>
            <div class="form-group">
                To: <input id="compose-recipients" class="form-control">
            </div>
            <div class="form-group">
                <input class="form-control" id="compose-subject" placeholder="Subject">
            </div>
            <textarea class="form-control" id="compose-body" placeholder="Body"></textarea>
            <input type="submit" class="btn btn-primary"/>
        </form>
    </div>
{% endblock %}

{% block script %}
    <script src="{% static 'mail/inbox.js' %}"></script>
{% endblock %}

JavaScript代码(原代码)

document.addEventListener('DOMContentLoaded', function() {

  // Use buttons to toggle between views
  document.querySelector('#inbox').addEventListener('click', () => load_mailbox('inbox'));
  document.querySelector('#sent').addEventListener('click', () => load_mailbox('sent'));
  document.querySelector('#archived').addEventListener('click', () => load_mailbox('archive'));
  document.querySelector('#compose').addEventListener('click', compose_email);
  document.querySelector('#compose-form').addEventListener('submit', submit_mail);


  // By default, load the inbox
  load_mailbox('inbox');
});

    // COMPOSE EMAIL

function compose_email() {

  // Show compose view and hide other views
  document.querySelector('#emails-view').style.display = 'none';
  document.querySelector('#compose-view').style.display = 'block';

  // Clear out composition fields
  document.querySelector('#compose-recipients').value = '';
  document.querySelector('#compose-subject').value = '';
  document.querySelector('#compose-body').value = '';
}

    // SENT EMAIL

function submit_mail(event) {

  // Post email to API route
  fetch('/emails' , {
    method: 'POST',
    body: JSON.stringify({
      recipients: document.querySelector('#compose-recipients').value,
      subject: document.querySelector('#compose-subject').value,
      body: document.querySelector('#compose-body').value
    })
  })
  .then(response => load_mailbox('sent'));
}

问题原因及修复方案

核心问题

  1. 表单默认提交行为未阻止:点击submit按钮时,浏览器会自动执行表单默认提交动作(刷新页面/跳转),导致JavaScript代码还没完成请求就被中断,看起来像没触发函数。
  2. 缺少必要请求头:Django需要CSRF令牌验证POST请求,且未声明请求体为JSON格式,服务器无法正确解析数据。
  3. 无错误处理:原代码未处理请求失败的情况,无法排查问题。

修复后的完整JavaScript代码

document.addEventListener('DOMContentLoaded', function() {

  // 切换视图按钮绑定事件
  document.querySelector('#inbox').addEventListener('click', () => load_mailbox('inbox'));
  document.querySelector('#sent').addEventListener('click', () => load_mailbox('sent'));
  document.querySelector('#archived').addEventListener('click', () => load_mailbox('archive'));
  document.querySelector('#compose').addEventListener('click', compose_email);
  document.querySelector('#compose-form').addEventListener('submit', submit_mail);

  // 默认加载收件箱
  load_mailbox('inbox');
});

// 撰写邮件
function compose_email() {
  // 切换显示视图
  document.querySelector('#emails-view').style.display = 'none';
  document.querySelector('#compose-view').style.display = 'block';

  // 清空输入框
  document.querySelector('#compose-recipients').value = '';
  document.querySelector('#compose-subject').value = '';
  document.querySelector('#compose-body').value = '';
}

// 发送邮件
function submit_mail(event) {
  // 1. 阻止表单默认提交行为
  event.preventDefault();

  // 2. 发送POST请求到后端
  fetch('/emails', {
    method: 'POST',
    // 添加必要请求头
    headers: {
      'Content-Type': 'application/json',
      'X-CSRFToken': getCookie('csrftoken')
    },
    body: JSON.stringify({
      recipients: document.querySelector('#compose-recipients').value,
      subject: document.querySelector('#compose-subject').value,
      body: document.querySelector('#compose-body').value
    })
  })
  .then(response => {
    // 处理响应状态
    if (response.ok) {
      load_mailbox('sent');
    } else {
      alert('发送失败,请检查收件人格式是否正确');
    }
  })
  .catch(error => {
    // 捕获请求错误
    console.error('请求出错:', error);
    alert('发送出错,请稍后重试');
  });
}

// 辅助函数:获取Django的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;
}

修复说明

  • event.preventDefault():阻止浏览器默认的表单提交动作,确保JavaScript代码完整执行。
  • 添加headers:包含Content-Type声明JSON格式,以及X-CSRFToken通过Django的CSRF验证。
  • 新增getCookie函数:从浏览器Cookie中获取CSRF令牌,这是Django处理POST请求的必要步骤。
  • 完善错误处理:通过response.ok判断请求是否成功,catch捕获网络错误,给用户明确提示,同时方便调试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:49:53