"Forbidden (CSRF token missing or incorrect.):" 使用 Django 和 JS
"Forbidden (CSRF token missing or incorrect.):" using Django and JS
我正在我的 JS 代码中使用 Axios 执行 POST 请求,以将一些信息发送到我本地托管的 Django 服务器。我的 html 代码表单中有 {% csrf_token %} 但不知道如何使用 Axios 发送 csrf 令牌。
我在终端中收到此错误:
“禁止(CSRF 令牌丢失或不正确。):/api/scoring/submit_score_details”。
如何在我的 axios post 中正确插入 csrf 令牌?现在,我认为 JS 无法像我那样读取 {{ csrf_token }} 。我一直在搜索 Stack,但似乎大多数人都在使用 jQuery 或其他类型的 JS。
为了节省 space 我没有 post 有效载荷中的变量是什么,但它们都是字符串。
如果我在 views.py 文件中将 @csrf_exempt 放在我的函数上方,我可以让错误消失。
{
let payload = {
"csrfmiddlewaretoken": "{{ csrf_token }}",
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
<div class="col text-center">
<button id="start" type="button" class="btn btn-primary btn-lg">
New Problem
</button>
<p id="math_problem"></p>
<form id="inputForm" method="POST">
{% csrf_token %}
<input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here">
<input id="correct_answer" type="hidden">
</form>
<br>
<button id="result_check" type="button" class="btn btn-primary btn-lg">Check</button>
<script src={% static 'js/game_logic.js' %}></script>
</div>
{
let payload = {
"csrfmiddlewaretoken": "{{ csrf_token }}",
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
<form id="inputForm" method="POST">
{% csrf_token %}
<input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here">
<input id="correct_answer" type="hidden">
</form>
您的 Axios 代码是否可能在页面中呈现 csrf_token 之前创建(通过 django 模板)?
尽早在您的 js 代码中尝试这样的事情:
var my_token = '{{ csrf_token }}';
然后当你调用 Axios 时,发送这个值,而不是渲染 {{ csrf_token }} 内联,所以像这样:
{
let payload = {
"csrfmiddlewaretoken": my_token,
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
我也很好奇你是否看到你的 csrf 令牌在你显示的代码中被打印到控制台(从打印出有效载荷),因为这将表明它是否被发送。
如果正在发送 csrf_token,应用程序可能会出现其他问题,但是一旦您在 my_token 中获得了令牌,您就可以将其打印出来并确保它已正确设置并从那里开始工作。
好吧,回顾一下讨论,我想我可能知道这里发生了什么......
也许你已经在你的 JS 中添加了“{{ csrf_token }}”(存储在静态代码中的某个地方)——这是行不通的,因为正如你所指出的,JS 对Django 模板。
这样做的方法是将您的 JS 代码更改为使用 JS 变量(例如 my_token)。
{
let payload = {
"csrfmiddlewaretoken": my_token, // populated later within form
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
此 my_token 值将在稍后(在您的表单中)进行 Axios 调用之前提供。为此,请在您的表单中添加:
<script>
// This will be rendered by Django to get the actual string into my_token
var my_token = "{{ csrf_token }}";
</script>
然后,当您进行 Axios 调用时(通过单击按钮或定时器或其他方式),应正确设置和使用此全局变量。
所以我最后做了一些谷歌搜索并问了一个朋友。我们想出了一个解决方案。
我们必须添加两行代码才能使事情正常进行:
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFToken';
我们还去掉了 'payload' 变量,将所有内容都放在 Axios 代码中。
{
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFToken';
axios.post('../api/scoring/submit_score_details', {
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
});
console.log(`Problem:${problem},
User Input: ${userInput},
Correct Answer: ${correctAnswer},
Question Status: ${questionStatus}`
);
};
<div class="col text-center">
<button id="new_problem_button" type="button" class="btn btn-primary btn-lg">
New Problem
</button>
<p id="math_problem"></p>
<form id="inputForm" method="POST">
{% csrf_token %}
<input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here">
<input id="correct_answer" type="hidden">
</form>
<br>
<button id="result_check" type="button" class="btn btn-primary btn-lg">Check</button>
<script src={% static 'js/game_logic.js' %}></script>
</div>
Here's link 对我们有帮助。
我正在我的 JS 代码中使用 Axios 执行 POST 请求,以将一些信息发送到我本地托管的 Django 服务器。我的 html 代码表单中有 {% csrf_token %} 但不知道如何使用 Axios 发送 csrf 令牌。
我在终端中收到此错误: “禁止(CSRF 令牌丢失或不正确。):/api/scoring/submit_score_details”。
如何在我的 axios post 中正确插入 csrf 令牌?现在,我认为 JS 无法像我那样读取 {{ csrf_token }} 。我一直在搜索 Stack,但似乎大多数人都在使用 jQuery 或其他类型的 JS。
为了节省 space 我没有 post 有效载荷中的变量是什么,但它们都是字符串。
如果我在 views.py 文件中将 @csrf_exempt 放在我的函数上方,我可以让错误消失。
{
let payload = {
"csrfmiddlewaretoken": "{{ csrf_token }}",
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
<div class="col text-center">
<button id="start" type="button" class="btn btn-primary btn-lg">
New Problem
</button>
<p id="math_problem"></p>
<form id="inputForm" method="POST">
{% csrf_token %}
<input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here">
<input id="correct_answer" type="hidden">
</form>
<br>
<button id="result_check" type="button" class="btn btn-primary btn-lg">Check</button>
<script src={% static 'js/game_logic.js' %}></script>
</div>
{
let payload = {
"csrfmiddlewaretoken": "{{ csrf_token }}",
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
<form id="inputForm" method="POST">
{% csrf_token %}
<input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here">
<input id="correct_answer" type="hidden">
</form>
您的 Axios 代码是否可能在页面中呈现 csrf_token 之前创建(通过 django 模板)?
尽早在您的 js 代码中尝试这样的事情:
var my_token = '{{ csrf_token }}';
然后当你调用 Axios 时,发送这个值,而不是渲染 {{ csrf_token }} 内联,所以像这样:
{
let payload = {
"csrfmiddlewaretoken": my_token,
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
我也很好奇你是否看到你的 csrf 令牌在你显示的代码中被打印到控制台(从打印出有效载荷),因为这将表明它是否被发送。
如果正在发送 csrf_token,应用程序可能会出现其他问题,但是一旦您在 my_token 中获得了令牌,您就可以将其打印出来并确保它已正确设置并从那里开始工作。
好吧,回顾一下讨论,我想我可能知道这里发生了什么......
也许你已经在你的 JS 中添加了“{{ csrf_token }}”(存储在静态代码中的某个地方)——这是行不通的,因为正如你所指出的,JS 对Django 模板。
这样做的方法是将您的 JS 代码更改为使用 JS 变量(例如 my_token)。
{
let payload = {
"csrfmiddlewaretoken": my_token, // populated later within form
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
}
console.log(payload);
axios.post('../api/scoring/submit_score_details', payload)
}
此 my_token 值将在稍后(在您的表单中)进行 Axios 调用之前提供。为此,请在您的表单中添加:
<script>
// This will be rendered by Django to get the actual string into my_token
var my_token = "{{ csrf_token }}";
</script>
然后,当您进行 Axios 调用时(通过单击按钮或定时器或其他方式),应正确设置和使用此全局变量。
所以我最后做了一些谷歌搜索并问了一个朋友。我们想出了一个解决方案。
我们必须添加两行代码才能使事情正常进行:
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFToken';
我们还去掉了 'payload' 变量,将所有内容都放在 Axios 代码中。
{
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFToken';
axios.post('../api/scoring/submit_score_details', {
"math_problem": problem,
"user_answer": userInput,
"true_answer": correctAnswer,
"question_status": questionStatus,
});
console.log(`Problem:${problem},
User Input: ${userInput},
Correct Answer: ${correctAnswer},
Question Status: ${questionStatus}`
);
};
<div class="col text-center">
<button id="new_problem_button" type="button" class="btn btn-primary btn-lg">
New Problem
</button>
<p id="math_problem"></p>
<form id="inputForm" method="POST">
{% csrf_token %}
<input id="user_input" autocomplete="off" class="form-control form-control-lg" type="text" placeholder="Type your answer here">
<input id="correct_answer" type="hidden">
</form>
<br>
<button id="result_check" type="button" class="btn btn-primary btn-lg">Check</button>
<script src={% static 'js/game_logic.js' %}></script>
</div>
Here's link 对我们有帮助。