Django CSRF 验证 – 使用 JavaScript 获取 POST 请求发送 FormData 对象

问题描述 投票:0回答:0

在使用 JavaScript

FormData
POST 请求将动态创建的
fetch
对象(包含图像文件)发送到 Django 端点时,我尝试使用 Django 的 CSRF 保护。我的问题是我无法成功将
csrf_token
附加到请求,这导致了
CSRF token missing
错误。

根据 Django 的 CSRF 文档,我已将

CSRF_COOKIE_HTTPONLY = True
包含在
settings.py
中,然后我在 HTML 文件中设置隐藏的
{% csrf_token %}
,并尝试在我的 JavaScript 文件中访问它:

// Create form to send image
let coverPhotoForm = new FormData();
        
// Read CSRF token and image file from DOM
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
const coverPhotoUpload = document.querySelector('#cover-photo-upload');

// Add CSRF token and image to form object
coverPhotoForm.append('X-CSRFToken', csrftoken)
coverPhotoForm.append('cover_photo', coverPhotoUpload.files[0]);

// Add image via POST request to endpoint
  fetch(`/profile/${profileUserId}`, {
    method: 'POST',
    body: coverPhotoForm,
    mode: 'same-origin'
  })
  .then( response => response.json())
  .then( response => {
    console.log(response)
  })
})

备注:

    通过
  1. csrftoken 检查时,
    console.log
    似乎已成功从 DOM 读取。
  2. 刷新页面后,图片上传成功,但每次发送请求仍然出现
    CSRF token missing
    错误。

我还尝试直接在上面的

fetch
请求中设置标头,并使用下面的 Django 文档示例,但这并没有改变任何内容。

const request = new Request(
    fetch(`/profile/${profileUserId},
    {
        method: 'POST',
        headers: {'X-CSRFToken': csrftoken},
        mode: 'same-origin'
    }
);

其他尝试:

  1. 我上面的设计改编自这篇SO帖子中接受的答案:Proper Django Fetch Validation
  2. 尝试将
    accept
    content-type
    键添加到我的请求中的
    headers
    字典中,建议此处:使用 JS/DjangoPOST 请求。
  3. 按照上面动态创建表单的 Django 文档链接中的“警告”中的建议,将
    @ensure_csrf_cookie
    装饰器添加到我的
    view
    中。
  4. 使用
    csrfmiddlewaretoken: '{{ csrf_token }}'
    (而不是
    querySelector
    从DOM读取):在JS中使用CSRF令牌
javascript django fetch-api django-csrf
© www.soinside.com 2019 - 2024. All rights reserved.