首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在POST-hyperlink中使用csrf-token?

如何在POST-hyperlink中使用csrf-token?
EN

Stack Overflow用户
提问于 2021-07-03 21:35:05
回答 1查看 105关注 0票数 1

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

下面是来自https://ru.stackoverflow.com/questions/65237/Вызов-метода-post-через-ссылку的函数

代码语言:javascript
复制
    <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>

我是这样称呼它的:

代码语言:javascript
复制
<a href="#" onclick="postToUrl('/account/add_to_blacklist/watched_user_id{{ message.recipient.user.id }}/next={{ request.get_full_path }}', {}, 'POST');">To blacklist</a>

这是我的观点:

代码语言:javascript
复制
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)

我试过了,但没什么用:

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

我也试着将它作为参数传递,但没有帮助:

代码语言:javascript
复制
csrfmiddlewaretoken: '{{ csrf_token }}' 

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

代码语言:javascript
复制
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错误。

代码语言:javascript
复制
        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);
                    }
                }
            });

请帮帮我!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-04 02:30:20

我在这里找到了一个解决方案:submitting a hyperlink by GET or POST

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

代码语言:javascript
复制
<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>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68236730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档