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

Django Ajax POST请求出现CSRF Token缺失或错误如何解决?

问题描述

我正在基于Django框架开发Web应用,尝试集成Ajax功能时遇到了简单Ajax调用无法正常运行的问题。
我的需求是:用户在表单中输入数据库凭据后,调用API建立数据库连接,最终返回连接成功或失败的结果。

相关代码

views.py 接口代码

class TestConnectionAPI(views.APIView):
    '''
    Test DB Connection from TARGET DB
    '''  
    def post(self, request):
        dbs = (request.data['host'],
                request.data['port'],
                request.data['dbname'],
                request.data['user'],
                request.data['password'],
                request.data['schema_name'])

        try:
            x = dc.DbConnection(*dbs)
            x.create_conn()
            data = x.check_conn()           
            
            result = {
                'message' : 'Success',
                'server' : f'Connection established from {data}',
                'results':{
                    'host':dbs[0],
                    'port':dbs[1],
                    'dbname':dbs[2]
                    },
            }
            return Response(result, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'Message':str(e)}, status=status.HTTP_400_BAD_REQUEST)

前端表单代码(connection.html)

<form method="post">
    <div class="modal-body">
        <div class="form-group">
            <label for="host">Hostname</label>
            <input type="text" class="form-control" id="host" name="host" aria-describedby="host">
        </div>
        <div class="form-group">
            <label for="port">Port</label>
            <input type="number" class="form-control" id="port" name="port" placeholder="e.g., 5432">
        </div>
        <div class="form-group">
            <label for="database">Database name</label>
            <input type="text" class="form-control" id="dbname" name="dbname" placeholder="Enter database name">
        </div>
        <div class="form-group">
            <label for="username">Username</label>
            <input type="text" class="form-control" id="user" name="user" placeholder="Enter username">
        </div>
        <div class="form-group">
            <label for="password">Password</label>
            <input type="password" class="form-control" id="password" name="password">
        </div>
        <div class="form-group">
            <label for="schema">Schema</label>
            <input type="text" class="form-control" id="schema_name" name="schema_name">
        </div>
    </div>
    <div class="modal-footer border-top-0 d-flex justify-content-center">
        <a href="#form2" class="btn btn-primary" data-toggle="modal" type="submit" id="btnSubmit">Test</a>
        <button type="submit" class="btn btn-success">Save</button>
    </div>
</form>

Ajax 请求代码

$('#btnSubmit').click(function () {
    let _host = $('#host').val();
    let _port = $('#port').val();
    let _dbname = $('#dbname').val();
    let _user = $('#user').val();
    let _password = $('#password').val();
    let _schema_name = $('#schema_name').val();

    var $crf_token = $('[name="csrfmiddlewaretoken"]').attr('value');

    $.ajax({
        type: 'POST',
        dataType: 'JSON',
        headers:{"X-CSRFToken": $crf_token},
        data:{
            "host" : _host,
            "port" : _port,
            "dbname" : _dbname,
            "user" : _user,
            "password" : _password,
            "schema_name": _schema_name,
        },
        url:"http://127.0.0.1:8000/api/v1/test/",
        error: function (xhr, status, error) {
            var err_msg = ''
            for (var prop in xhr.responseJSON) {
                err_msg += prop + ': ' + xhr.responseJSON[prop] + '\n';
            }
            alert(err_msg);
        },
        success: function (result) {
            console.log(result);
        }
    });
});

问题现象

  • 报错与CSRF Token相关,请求无法正常触发接口返回结果
  • 预期接口成功响应格式如下:
{
    "message": "Success",
    "server": "Connection established from ('PostgreSQL 12.7, compiled by Visual C++ build 1914, 64-bit',)",
    "results": {
        "host": "localhost",
        "port": 5432,
        "dbname": "dvdrental"
    }
}
解决方案

按以下步骤逐一修复即可:

  1. 补全表单CSRF标签:在<form method="post">下第一行添加Django模板标签{% csrf_token %},确保页面渲染后生成name为csrfmiddlewaretoken的隐藏输入框
  2. 修正CSRF Token取值逻辑:将JS中获取token的代码替换为
var $crf_token = $('input[name="csrfmiddlewaretoken"]').val();
  1. 阻止a标签默认跳转行为:绑定点击事件的元素是a标签,默认跳转行为会中断Ajax请求,修改点击事件开头新增阻止逻辑
$('#btnSubmit').click(function (e) {
    e.preventDefault(); // 新增这行
    // 原有逻辑保持不变
});
  1. 确认当前页面域名和Ajax请求的域名一致,避免跨域导致CSRF校验失败

修复完成后重新测试,成功响应会直接打印在浏览器控制台,可按需添加逻辑将结果渲染到页面。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:54:02