Django CSRFToken 中间件附加到 URL 并在向服务器发出“PUT”请求后显示。 (AJAX 问题)

Posted

技术标签:

【中文标题】Django CSRFToken 中间件附加到 URL 并在向服务器发出“PUT”请求后显示。 (AJAX 问题)【英文标题】:Django CSRFToken middleware appends to URL and shows up after making a “PUT” request to the server. (AJAX issue) 【发布时间】:2021-04-07 00:37:05 【问题描述】:

我正在开发一个 Django Python/javascript 项目。 PUT 请求通过客户端完成并发送回服务器。成功发送请求后,页面刷新,导致 URL 中的 csrf token 中间件暴露。我已经实现了 AJAX返回 false,添加了一个 event.preventDefault(),通过 header 传递了一个 cookie在 fetch 中,使用了 async 函数,并添加了 try and catch 语法。而且我不知道为什么它不影响重新提交。提交完成后,我需要停止网页刷新,以便 csrf_token 不会显示附加到 URL。

希望有人可以让我知道我在这里没有看到什么。谢谢!

// Set global variables to use in form submission
var id, upt_prodName, upt_prodPrice, upt_prodDescpt;

// Block to populate textarea that allows the user to update product info.
 
 const editProd_view = (response) => 
 
  let prod_id = response.id;
  let edit_name = response.name;
  let edit_price = response.price;
  let edit_descpt = response.description;
 
 
 let prod_idUpt = (document.querySelector("#prod_idUpt").innerhtml = prod_id);
 let new_name = (document.querySelector(
  "#editProdName"
   ).innerHTML = edit_name);
 let new_price = (document.querySelector(
  "#editProdPrice"
   ).innerHTML = edit_price);
 let new_textarea = (document.querySelector(
  "#editProdDescpt"
   ).innerHTML = edit_descpt);
 
 id = prod_id;
 
//On submit, send product info to update the product.

 const edit_prod = (document.querySelector(
  "#editProd_form").onsubmit = async () => 
     try 

// Get all values from textarea to update content.
     upt_prodName = document.getElementById("editProdName").value;
     new_prodPrice = document.getElementById("editProdPrice").value;
     new_prodDescpt = document.getElementById("editProdDescpt").value;
 
     const res = await fetch(
       `/editProduct/$id`,
          
    method: "PUT",
    headers: 
    "Content-Type": "application/json",
    "X-CSRFToken": getCookie("csrftoken"),
    ,
    body: JSON.stringify(
      name: upt_prodName,
      description: upt_prodDescpt,
      price: upt_prodPrice,
     ),
    )
    .then((res) => res.json())
    .then((result) => 
console.log("result ->", result);
    );
 catch (err) 
  console.error("err", err);


//Once the post has been submitted, return false to prevent reloading.

 edit_prod.handleForm();
 return false;
 );

return false;
;

【问题讨论】:

【参考方案1】:

是的,在 django 中用于 post 和 put,delete 需要一个 csrf 令牌,我的解决方案

你可以这样做

<form>
 <button id="onsubmit" method="csrf_token">submit</button>
</form>

$(document).on(function() 
   $(document).on('click', '#onsubmit', function() 
      var token = $(this).attr("method")
      const res = await fetch(
       `/editProduct/$id`,
          
    method: "PUT",
    headers: 
    "Content-Type": "application/json",
    "X-CSRFToken": token,
    ,
    body: JSON.stringify(
      name: upt_prodName,
      description: upt_prodDescpt,
      price: upt_prodPrice,
     ),
    )
    .then((res) => res.json())
    .then((result) => 
console.log("result ->", result);
    );
 catch (err) 
  console.error("err", err);

   )
)

【讨论】:

谢谢,我尝试实施您的解决方案,但这不是我所需要的。当发送“PUT”请求时,它会在服务器中进行更新,但在此过程中,网页会刷新以获取项目列表并将其与所做的更改一起显示。在这种情况下,就是 csrf_token 暴露的时候。因此,我认为问题可能出在对该网页上项目列表的“GET”请求中。这就是为什么我试图阻止网页在提交完成后刷新。

以上是关于Django CSRFToken 中间件附加到 URL 并在向服务器发出“PUT”请求后显示。 (AJAX 问题)的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 如何像 Django、Laravel 一样创建元标记来存储 `csrftoken`?

django中csrftoken跨站请求伪造的几种方式

django 在 cookie 中没有 csrftoken

无法在 Django 网站中发布跨源请求

中间件.Django

Django中间件CsrfViewMiddleware源码分析