【问题标题】:Django Rest Framework - DELETE ajax call failure due to incorrect CSFR tokenDjango Rest Framework - 由于不正确的 CSRF 令牌而删除 ajax 调用失败
【发布时间】:2015-01-18 03:41:41
【问题描述】:

我正在尝试使用 django rest 框架来轻松处理一些模型作为 restful 资源。 这是我的代码:

Django: 1.7.1

Django REST Framework: 2.4.4

jQuery: 2.1.1

# models.py

class DocumentNodeTemplate(MPTTModel):
    """

    """
    document_template = models.ForeignKey(
        DocumentTemplate,
        related_name="nodes",
        verbose_name="Document template"
    )
    parent = TreeForeignKey(
        'self',
        null=True, blank=True,
        related_name='children'
    )
    section_template = models.ForeignKey(
        'SectionTemplate',
        related_name="node_templates",
        verbose_name="Section template"
    )

    def __unicode__(self):
        return  self.section_template.name

    def get_class(self):
        type = self.section_template.type
        return import_string(type)


# serializers.py

class DocumentNodeTemplateSerializer(serializers.ModelSerializer):
    class Meta:
        model = DocumentNodeTemplate
        fields = ('document_template', 'parent', 'section_template')


# views.py

class DocumentNodeTemplateAPIView(CreateAPIView, RetrieveUpdateDestroyAPIView):
    queryset = DocumentNodeTemplate.objects.all()
    serializer_class = DocumentNodeTemplateSerializer


<!-- HTML (section - admin's change form customization)-->
<fieldset class="module aligned">
    <h2>{{ node_fieldset_title }}</h2>
    <div class="form-row document-nodes">
        <div
        style="width: 100%; min-height: 450px;" id="general-container"
        data-document_model="{{ document_model }}"
        >
            <form id="changelist-form" action="" method="post" novalidate>{% csrf_token %}
                <div id="tree-container">
                    <div id="tree"
                         data-url="{{ tree_json_url }}"
                         data-save_state="{{ app_label }}_{{ model_name }}"
                         data-auto_open="{{ tree_auto_open }}"
                         data-autoescape="{{ autoescape }}"
                            >
                    </div>
                    <div class="add-node">
                        <a href="/admin/document/{{ model_name }}/add/?_to_field=id&document_id={{ object_id }}" class="add-another"
                            onclick="return showCustomAddAnotherPopup(event, this);">
                            <img src="/sitestatic/admin/img/icon_addlink.gif" width="10" height="10"
                                 alt="Add another node"> Add another node
                        </a>
                    </div>
                    <ul class='node-custom-menu'>
                        <li data-action="delete">Delete node</li>
                    </ul>
                </div>
            </form>
            <div id="node-container">
                <h3 id="node-name"></h3>
                <br/>

                <div id="node-content"></div>
            </div>
        </div>
    </div>
</fieldset>


// javascript 
var performCRUDaction = function(action, api_url, callback) {
var csfrtoken = $('input[name="csrfmiddlewaretoken"]').prop('value');
var _reloadNodeTree = function () {
    window.nodeTree.tree('reload');
}
var _performAction = function () {
    jQuery.ajax({
            type: actionType,
            url: api_url,
            data: { 'csrfmiddlewaretoken': csfrtoken },
            success: function () {
                console.log("action " + action + " successfully performed on resource " + api_url);
                _reloadNodeTree();
            },
            error: function () {
                console.log("action " + action + " failed on resource " + api_url);
            }
        });
    }


    var actionType,
        documentModel = null;
    var nodeDataObj = {};
    switch (action) {
        case "delete":
            actionType = "DELETE";
            break;
        case "update":
            actionType = "PUT";
            break;
        case "create":
            actionType = "POST";
            break;
        case "retrieve":
            actionType = "GET";
            break;
    }
    _performAction();
    callback();
}

我没有贴出所有代码,反正当那个ajax调用被触发时,我得到一个403错误:

// headers

Remote Address:127.0.0.1:8050
Request URL:http://127.0.0.1:8050/api/documentnodetemplates/46
Request Method:DELETE
Status Code:403 FORBIDDEN
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-GB,en;q=0.8,en-US;q=0.6,it;q=0.4
Cache-Control:no-cache
Connection:keep-alive
Content-Length:52
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:djdt=hide; sessionid=x5cw6zfifdene2p7h0r0tbtpkaq7zshq; csrftoken=NyMqLlKxeeAdc4Eq2nFpFOebh0SUBBVY
Host:127.0.0.1:8050
Origin:http://127.0.0.1:8050
Pragma:no-cache
Referer:http://127.0.0.1:8050/admin/document/documenttemplate/1/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
X-CSRFToken:NyMqLlKxeeAdc4Eq2nFpFOebh0SUBBVY
X-Requested-With:XMLHttpRequest
Form Dataview sourceview URL encoded
csrfmiddlewaretoken:NyMqLlKxeeAdc4Eq2nFpFOebh0SUBBVY
Response Headersview source
Allow:GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type:application/json
Date:Thu, 20 Nov 2014 09:52:31 GMT
Server:WSGIServer/0.1 Python/2.7.6
Vary:Accept, Cookie
X-Frame-Options:SAMEORIGIN

// response
{"detail": "CSRF Failed: CSRF token missing or incorrect."}

有人遇到过相同或类似的问题并可以提供帮助吗?

谢谢 陆克

【问题讨论】:

    标签: ajax django rest django-rest-framework django-csrf


    【解决方案1】:

    您应该删除所有 Cookie 和其他站点和插件数据以及缓存的图像和文件,方法是进入历史选项卡,然后清除浏览数据...另一种选择是在基于类的视图中使用 @csrf_exempt 装饰器。

    【讨论】:

    • 缓存被禁用,因为我使用 Chrome 并打开了开发工具栏,我可以再次检查刷新历史记录。使用@csrf_exempt 不是解决方案,因为它消除了CSFR 保护
    • 那你为什么不试试隐身窗口呢?
    • 没办法。尝试使用 Firefox 并清除历史记录,结果相同
    • 运气好,出了什么问题?
    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 2014-05-13
    • 2017-09-10
    • 2017-09-14
    • 1970-01-01
    • 2020-09-19
    • 2021-07-14
    • 2017-10-02
    相关资源
    最近更新 更多