Django 应用程序中的 Reportlab 错误 - 禁止(CSRF 令牌丢失或不正确。)

Reportlab in Django Application error - Forbidden (CSRF token missing or incorrect.)

我更多的是数据科学背景,但为了好玩,我一直在构建一个网络应用程序。我是 django、javascript 和 HTML 的新手,我需要花很多时间思考 - 所以如果我的编码看起来不合常规,我深表歉意。随时提供任何反馈。在我的应用程序中,我试图在执行以下操作的网页上创建一个按钮:

  1. 读取用户在 JavaScript 中输入的 HTML table 的数据输入(作为数组)。
  2. 使用 ajax,将数据发送到 Python 视图。
  3. 在那里,将对数组执行一个函数,输出将作为 reportlab 库生成的 PDF 返回给用户。

不幸的是,我继续收到以下错误:

Forbidden (CSRF token missing or incorrect.): /get_custom_bingo

这是完整的错误:

Forbidden (CSRF token missing or incorrect.): /get_custom_bingo
[03/Sep/2021 16:07:17] "POST /get_custom_bingo HTTP/1.1" 403 2513
[03/Sep/2021 16:07:17] "POST /pages/custom_bingo.html HTTP/1.1" 200 4320
[03/Sep/2021 16:07:17] "GET /static/JS/scripts.js HTTP/1.1" 304 0

我试图让它消失,但我在网上找不到的任何东西似乎都无法帮助我目前的情况。有人知道如何解决这个问题吗? (请参阅下面我的代码的相关部分):

custom_bingo.html

<form action="" method="POST">
    {% csrf_token %}
    <button class="button Submit" onclick="getCol();" />Submit</button>
</form>
<script type="text/javascript" src={% static "JS/jquery-3.6.0.min.js" %}></script>
<script type="text/javascript" src={% static "JS/scripts.js" %}></script>

JS

function getCol()
{
    var table = document.getElementById('tbl');
    var column = [];
    for(var i = 0; i<table.rows.length; i++){
        column.push(table.rows[i].cells[1].childNodes[0].value);
    }
    alert(column)
    $.ajax({
        headers: {'X-CSRFToken': '{{ csrf_token }}'},
        url: '/get_custom_bingo',
        type: 'POST',
        data: {'arr':column}
      });
}

views.py

def custom_bingo(request):
    return render(request, "bingo/pages/custom_bingo.html")

def get_custom_bingo(request):
    a = request.POST.getlist('arr[]')
    arr_lis = app_models.custom_shuff(a, 150, True) #function imported from models.py
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = f'inline; filename="bingo.pdf"'
    buffer = io.BytesIO() 
    doc = SimpleDocTemplate(buffer, pagesize = letter)
    # container for the 'Flowable' objects
    elements = []
    for arr in arr_lis:
        data = arr
        t = Table(data, 5 * [1.5 * inch], 6 * [1.4 * inch])
        # from (column, row) to (column, row)
        t.setStyle(TableStyle([...])) #table styles here
        elements.extend([t, PageBreak()])
    # write the document to disk
    doc.build(elements)
    response.write(buffer.getvalue())
    buffer.close()
    return response

urls.py

app_name = 'bingo'

urlpatterns = [
    ...
    path('pages/custom_bingo.html', views.custom_bingo),
    path('get_custom_bingo', views.get_custom_bingo, name='get_custom_bingo')
]

从 html 获取你的 csrftoken,而不是在你的 js 中(它不会)。

function getCol()
{
    var table = document.getElementById('tbl');
    var column = [];
    for(var i = 0; i<table.rows.length; i++){
        column.push(table.rows[i].cells[1].childNodes[0].value);
    }
    const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
    alert(column, csrftoken )
    $.ajax({
        headers: {'X-CSRFToken': csrftoken},
        url: '/get_custom_bingo',
        type: 'POST',
        data: {'arr':column}
      });
}