如何在POST超链接中使用csrf令牌



我需要在Django中为POST请求创建一个超链接。例如;添加到黑名单";在菜单中。使用带有提交按钮的表单很容易,但我需要的是菜单项而不是按钮。我找到了执行此操作的Javascript代码,但它给了我一个错误403:CSRF令牌丢失或不正确。我找不到关于如何将csrf令牌插入Javascript函数的信息。我不懂Javascript,我是用Python写的。

这是来自的函数https://ru.stackoverflow.com/questions/65237/В

<script type="text/javascript">
function postToUrl(path, params, method) {
method = method || "post"; 
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
for(var key in params) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);
form.appendChild(hiddenField);
}
document.body.appendChild(form);
form.submit();
}
</script>

我是这样称呼它的:

<a href="#" onclick="postToUrl('/account/add_to_blacklist/watched_user_id{{ message.recipient.user.id }}/next={{ request.get_full_path }}', {}, 'POST');">To blacklist</a>

这是我的观点:

class AddToBlacklistView(View):
def post(self, request, watched_user_id, next_url=None, *args, **kwargs):
if not next_url:
next_url = '../profile.html/user_id{0}'.format(watched_user_id)
if request.user.is_authenticated:
try:
user = User.objects.select_related("profile").get(username=request.user)
watched_user = User.objects.select_related("profile").get(id=watched_user_id)
except User.DoesNotExist:
raise Http404
if watched_user.id == user.id:
return redirect(next_url)
if watched_user not in user.profile.blacklist.all():
user.profile.blacklist.add(watched_user)
user.save()
if watched_user.profile in user.profile.friends.all():
user.profile.friends.remove(watched_user.profile)
if user.profile in watched_user.profile.friends.all():
friendship = Friendship.objects.get(user=watched_user.profile, friend=user.profile)
if friendship.status != 3:
friendship.status = 2
friendship.save()
if watched_user in user.profile.bookmarks.all():
user.profile.bookmarks.remove(watched_user)
return redirect(next_url)
else:
return redirect(next_url)

我试过了,但没有帮助:

<meta name="csrf-token" content="{{ csrf_token }}">
<script>
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
</script>

我也试着作为参数通过,但没有帮助:

csrfmiddlewaretoken: '{{ csrf_token }}' 

Upd:我还尝试为视图添加装饰器,但它继续抛出相同的错误:

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
@method_decorator(csrf_protect)
def post ...

我还在用调用Javascript函数的HTML渲染页面的视图上尝试了@method_decorator(ensure_csrf_cookie(,但仍然得到403错误。

我还从中尝试了此代码https://docs.djangoproject.com/en/3.0/ref/csrf/并且它继续抛出相同的403错误。

function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});

请帮帮我!

我在这里找到了一个解决方案:通过GET或POST 提交超链接

我不得不修改它,因为在我的页面上有一个人员列表,每个人都有一个菜单:

<form id="myform1_{{ message.recipient.user.id }}" method="post" action="/account/add_to_blacklist/watched_user_id{{ message.recipient.user.id }}/next={{ request.get_full_path }}" >
{% csrf_token %}
</form>
<a href="#" onclick="document.getElementById('myform1_{{ message.recipient.user.id }}').submit();">Add to blacklist</a>

最新更新