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

Django部署至Apache服务器后Fetch提交表单返回403 Forbidden错误求助

Django部署至Apache服务器后Fetch提交表单返回403 Forbidden错误求助

兄弟,看你卡这个问题好几天了,太懂这种本地跑顺风顺水,一部署就掉坑的滋味!结合你给的代码和描述,我给你梳理几个大概率的问题点,你挨个排查试试:


1. Fetch请求的Content-Type设置冲突(大概率是403的元凶)

你在main.js里手动设置了headers: { 'Content-Type': 'application/x-www-form-urlencoded' },但同时用了new FormData(form)作为请求体——这俩是完全不兼容的!

FormData默认对应的Content-Type是multipart/form-data; boundary=xxx,浏览器会自动生成这个头。你强行改成x-www-form-urlencoded后,服务器没法正确解析FormData里的内容,包括表单里的CSRF令牌,Django的CSRF验证自然就失败了,直接返回403。

解决办法:把fetch里的手动Content-Type配置删掉,让浏览器自动处理,同时手动带上CSRF令牌做双重保险。修改后的代码如下:

const form = document.getElementById('form');
form.addEventListener("submit", submitHandler);

// 新增获取CSRF cookie的函数
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;
}

function submitHandler(e) {
    e.preventDefault();
    fetch("{% url 'messages-api' %}", {
        credentials: "include",
        method: 'POST',
        headers: { 
            'X-CSRFToken': getCookie('csrftoken')
        },
        body: new FormData(form)
    })
    .then(response => response.json())
    .then(data => {
        alert("Got your message")
    })
    .catch(err => console.error('请求出错:', err)); // 加个catch方便排查前端报错
}

2. 去掉Content-Type后出现500?大概率是邮件发送的锅

你说去掉那个头后,表单能存进数据库,但过两分钟报500,这说明表单提交本身是成功的,问题出在服务器端发送邮件的环节。本地能发邮件,生产环境不行,常见原因有:

  • Django的邮件配置(settings.py里的EMAIL_HOST、EMAIL_PORT、EMAIL_HOST_USER等)在生产环境是不是没配置对?比如SMTP服务器需要SSL/TLS,本地可能忽略了,但生产环境必须开启EMAIL_USE_SSL或EMAIL_USE_TLS。
  • Apache的运行用户(一般是www-data)有没有权限访问邮件相关资源?或者服务器防火墙是不是挡住了SMTP端口(比如25、465、587)?
  • 邮件发送超时!本地测试邮件发送很快,但生产环境SMTP连接慢,导致请求超时触发500错误。

解决办法:立刻去看Django的日志或者Apache的错误日志(一般在/var/log/apache2/目录下),找到500错误的具体堆栈信息,日志会明确告诉你是SMTP连接失败、认证错误还是超时,一目了然。


3. 再确认下权限配置(虽然你改了,但再检查一遍)

你给了templates文件夹权限,但还要确认:

  • Apache的运行用户(www-data)对/home/admin/pinpoint整个目录有没有读权限?尤其是venv虚拟环境和project目录。
  • media文件夹有没有写权限?不过你说表单能存数据库,这个可能不是问题,但以防万一。
  • 你的ssl.conf里的路径是不是都正确?比如WSGIScriptAlias / /home/admin/pinpoint/project/wsgi.py这个路径有没有写错?

按这个顺序排查,先搞定Content-Type的问题解决403,再通过日志定位500的邮件问题,应该就能顺利解决了!

备注:内容来源于stack exchange,提问作者user13506452

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 16:44:52