django 403从我自己的服务器获取时出错:缺少CSRF令牌

osh3o9ms  于 2022-11-18  发布在  Go
关注(0)|答案(1)|浏览(125)

我有一个类似社交媒体的页面,显示每个用户的所有帖子,用户可以通过编辑按钮编辑自己的帖子。当点击编辑按钮时,会显示一个预先填充了帖子内容的文本区域,以及一个保存和取消按钮。
单击“保存”按钮时,我发出提取请求以更新内容而不重新加载页面。但是,我得到403,因为缺少csrf标记。令我困惑的是,我的HTML模板中没有表单。我应该将{% csrf_token %}放在哪里?
network.js:

function clearEditView(postId) {
// Show edit button and original content
document.getElementById(`edit_button_${postId}`).style.display = "block";
document.getElementById(`content_${postId}`).style.display = "block";
// Hide edit form
document.getElementById(`edit_form_${postId}`).style.display = "none";

}

document.addEventListener('DOMContentLoaded', function() {

    // Add event listener that listens for any clicks on the page
    document.addEventListener('click', event => {
        
        // Save the element the user clicked on
        const element = event.target;

        // If the thing the user clicked is the edit button
        if (element.id.startsWith('edit_button_')) {
            
            // Save necessary variables
            const editButton = element;
            const postId = editButton.dataset.id;
            const saveButton = document.getElementById(`save_${postId}`);
            const cancelButton = document.getElementById(`cancel_${postId}`);
            const postText = document.getElementById(`content_${postId}`);

            // Hide edit button and original content
            editButton.style.display = "none";
            postText.style.display = "none";

            // Show edit form
            document.getElementById(`edit_form_${postId}`).style.display = "block";

            // Prepopulate the text area
            const textArea = document.getElementById(`new_content_${postId}`);
            textArea.innerHTML = postText.innerHTML;

            // Event listener for when user clicks new 'Cancel' button
            cancelButton.addEventListener('click', function() {
                clearEditView(postId)
            })

            // Event listener for when user clicks new 'Cancel' button
            saveButton.addEventListener('click', function() {
                const new_content = document.getElementById(`new_content_${postId}`).value;

                // Make fetch request to update page without full reload
                fetch(`/edit/${postId}`, {
                    method: 'POST',
                    body: JSON.stringify({
                        // Pass through the new content typed in the text area
                        content: new_content,
                    })
                })
                
                .then(response => response.text())
                .then(result => {
                        // Sets on screen text to what the user edited
                        postText.innerHTML = result.content;
                        
                        // Removes all edit fields and restores to normal view
                        clearEditView(postId)
                })
                .catch(error => {
                    console.error(error);
                })
            })
        }
        
    })
})

index.html:

{% for post in page_obj %}
    {{ post.full_name|upper }}<br>
    
        <div class="frame">
            <h4><a href="{% url 'profile' post.user.username %}" style="color: black;">{{post.user.username}}</a></h4>
            {% if user.is_authenticated and post.user == user %}
                <button class="btn btn-sm btn-outline-primary" data-id="{{post.id}}" id="edit_button_{{post.id}}">Edit</button>
            {% endif %}
            <div id="content_{{post.id}}">{{post.content}}</div>
            <div id="edit_form_{{post.id}}" style="display: none;">
                <div class="form-group"><textarea id="new_content_{{post.id}}" name="new_content" cols="30"></textarea></div>
                <button class="btn btn-sm btn-success" id="save_{{post.id}}" >Save</button>
                <button class="btn btn-sm btn-danger" id="cancel_{{post.id}}">Cancel</button>
            </div>
            
            <div class="grey" id="timestamp">{{post.date}}</div>
            <div class="grey">{{post.likes}}</div>
            <a href="#" style="color: grey;">Comment</a>
        </div>
{% endfor %}

views.py:

def edit(request, post_id):
    if request.method == "POST":
        post = AllPost.objects.get(pk = post_id)
        body_unicode = request.body.decode('utf-8')
        body = json.loads(body_unicode)
        content = body['content']

        # Updates post with new content
        AllPost.objects.filter(pk=post_id).update(content=f'{content}')

        # Returns Json Response with content passed back that we can use with JS to update page
        return JsonResponse({"message": "Post updated successfully.", "content": content}, status=200)
    else:
        return JsonResponse({"error": "You do not have permission to do this"}, status=400)
nfg76nw0

nfg76nw01#

更改:

fetch(`/edit/${postId}`, {
                    method: 'POST',
                    body: JSON.stringify({
                        // Pass through the new content typed in the text area
                        content: new_content,
                    })
                })

收件人:

let csrftoken = '{{ csrf_token }}'
fetch(`/edit/${postId}`, {
                    method: 'POST',
                   headers:{'X-CSRFToken':csrftoken},
                    mode : 'same-origin',
                    body: JSON.stringify({
                        // Pass through the new content typed in the text area
                        content: new_content,
                    })
                })

相关问题