我需要在Django中为POST请求创建一个超链接。例如,菜单中的“添加到黑名单”。这很容易做一个表单与提交按钮,但我需要一个菜单项,而不是按钮。我找到了执行此操作的Javascript代码,但它给出了一个错误403: CSRF令牌丢失或不正确。我也找不到关于如何将csrf-token插入Javascript函数的不稳定信息。我不懂Javascript,我是用Python写的。
下面是来自https://ru.stackoverflow.com/questions/65237/Вызов-метода-post-через-ссылку的函数
<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 }}' 更新:我也尝试为视图添加装饰器,但它继续抛出相同的错误:
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
@method_decorator(csrf_protect)
def post ...我还在视图上尝试了@ method_decorator(ensure_csrf_cookie),该视图使用调用Javascript函数的超文本标记语言呈现页面,但我仍然得到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);
}
}
});请帮帮我!
发布于 2021-07-04 02:30:20
我在这里找到了一个解决方案:submitting a hyperlink by GET or 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>https://stackoverflow.com/questions/68236730
复制相似问题