django 禁止(CSRF令牌丢失,)

pkwftd7m  于 2023-08-08  发布在  Go
关注(0)|答案(1)|浏览(118)

我在一个Django项目中工作,当我运行下面的代码时,我在VSCode控制台中得到了这个错误:
禁止(CSRF令牌丢失。):Copyright © 2018 - 2019 www.cnjs.com版权所有
请在下面找到我的代码的基础:

edit_post.html

{% extends "network/layout.html" %}

{% block body %}

    <h2>Edit Post</h2>

    <form id="edit-post-form" action="{% url 'edit_post' post.id %}" method="post" data-post-id="{{ post.id }}">
        {% csrf_token %}
        <div class="form-group">
            <textarea class="form-control" name="content" rows="3">{{ post.content }}</textarea>
        </div>
        <button class="btn btn-primary" type="submit">Save Changes</button>
    </form>

    <!-- Javascript code for saving the post -->
    <script>
        document.getElementById('edit-post-form').addEventListener('submit', function (event) {
            event.preventDefault();  // Prevent form submission

            var form = event.target;
            var postId = form.getAttribute('data-post-id');
            var content = form.elements['content'].value;
            var csrfToken = document.getElementsByName('csrfmiddlewaretoken')[0].value;

            var xhr = new XMLHttpRequest();
            xhr.open('POST', form.action, true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.setRequestHeader('X-CSRFToken', csrfToken);

            xhr.onload = function () {
                if (xhr.status === 200) {
                    var response = JSON.parse(xhr.responseText);
                    if (response.success) {
                        // Post updated successfully, redirect to index page
                        window.location.replace('/');
                    } else {
                        // Handle error response (if applicable)
                        console.error(response.message);
                    }
                } else {
                    // Handle non-200 status codes (if applicable)
                    console.error('Error saving post');
                }
            };

            xhr.onerror = function () {
                // Handle request error (if applicable)
                console.error('Error saving post');
            };

            var requestData = 'content=' + encodeURIComponent(content);
            xhr.send(requestData);
        });
    </script>

{% endblock %}

字符串

index.html

{% extends "network/layout.html" %}

{% block body %}
    
    <h2>All Posts</h2>

    <!-- New post -->
    {% if user.is_authenticated %}
        <form action="{% url 'index' %}" method="post">
            {% csrf_token %}
            <div class="form-group">
                <textarea class="form-control" name="content" rows="3" placeholder="Write a new post"></textarea>
            </div>
            <button class="btn btn-primary" type="submit">Post</button>
        </form>
    {% else %}
        <p>Please log in to write a new post.</p>
    {% endif %}

    <!-- Shows all the posts (10 on a page) -->
    <hr>
    {% for post in page_obj %}
        <div class="card mb-2">
            <div class="card-body">
                <h5 class="card-title">
                    <a href="{% url 'profile' username=post.user.username %}">@{{ post.user.username }}</a>
                </h5>
                <!-- <p class="card-text">{{ post.content }}</p> -->
                <div id="post-content-{{ post.id }}">
                    <p class="card-text">{{ post.content }}</p>
                </div>
                <p class="card-text"><small class="text-muted">Posted at {{ post.timestamp }}</small></p>
                <!--<p class="card-text">Likes: {{ post.likes.count }}</p> -->
                <p class="card-text">Likes: 0</p>

                <!-- Edit button-->
                {% if post.user == request.user %}
                    <!--<a href="{% url 'edit_post' post.id %}" class="btn btn-primary">Edit</a>-->
                    <button class="btn btn-primary" onclick="editPost('{{ post.id }}')">Edit</button>
                {% endif %}

            </div>
        </div>
    {% empty %}
        <p>No posts yet.</p>
    {% endfor %}

    {% if page_obj.has_previous %}
        <a href="?page={{ page_obj.previous_page_number }}" class="btn btn-primary">Previous</a>
    {% endif %}

    {% if page_obj.has_next %}
        <a href="?page={{ page_obj.next_page_number }}" class="btn btn-primary">Next</a>
    {% endif %}

    <script>
        function editPost(postId) {
            // Get the post content element
            var postContent = document.getElementById('post-content-' + postId);

            // Get the current content of the post
            var content = postContent.textContent.trim();

            // Create a textarea element
            var textarea = document.createElement('textarea');
            textarea.className = 'form-control custom-textarea';
            textarea.name = 'content';
            textarea.rows = '6';
            textarea.value = content;

            // Replace the post content with the textarea
            postContent.innerHTML = '';
            postContent.appendChild(textarea);

            // Set the cursor position to the end of the textarea
            textarea.focus();
            textarea.setSelectionRange(content.length, content.length);

            // Add a space between the textarea and the button
            postContent.appendChild(document.createElement('br'));

            // Create a button to save the changes
            var saveButton = document.createElement('button');
            saveButton.className = 'btn btn-primary';
            saveButton.textContent = 'Save Changes';
            saveButton.addEventListener('click', function() {
                saveChanges(postId, textarea.value);
            });

            // Add the save button below the textarea
            postContent.appendChild(saveButton);
        }

        function saveChanges(postId, newContent) {
            // Send an AJAX request to update the post content
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/edit_post/' + postId, true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.onload = function() {
                if (xhr.status === 200) {
                    // Post updated successfully, handle the response if needed
                    console.log('Post updated successfully');
                    // Redirect to the index page
                    window.location.replace('/');
                } else {
                    // Handle error response (if applicable)
                    console.error('Error saving post');
                }
            };

            xhr.onerror = function() {
                // Handle request error (if applicable)
                console.error('Error saving post');
            };
            xhr.send('content=' + encodeURIComponent(newContent));
        }
    </script>

{% endblock %}

views.py

@login_required(login_url='login')
def edit_post(request, post_id):
    post = get_object_or_404(Post, id=post_id)

    # Check if the current user is the owner of the post
    #
    if request.user != post.user:
        return JsonResponse({'success': False, 'message': 'You do not have permission to edit this post.'})

    # Update the content of the post
    #
    if request.method == 'POST':
        content = request.POST['content']
        post.content = content
        post.save()
        #return redirect('index')
        return JsonResponse({'success': True})

    # Render the edit post form
    #
    return render(request, 'network/edit_post.html', {
        'post': post
    })

url.py

from django.urls import path

from . import views

urlpatterns = [
    path("", views.index, name="index"),
    path("login", views.login_view, name="login"),
    path("logout", views.logout_view, name="logout"),
    path("register", views.register, name="register"),
    path("all_posts", views.all_posts, name="all_posts"),
    path("profile/<str:username>", views.profile, name="profile"),
    path("follow_unfollow/<str:username>", views.follow_unfollow, name="follow_unfollow"),
    path("following", views.following, name="following"),
    path("edit_post/<int:post_id>", views.edit_post, name="edit_post"),
]


我已经查看了一些关于如何使用Django和JavaScript管理CSRF的链接,但我仍然无法解决这个问题。我已经清理了我的浏览器的缓存。
你能帮我解决这个问题吗?

7kqas0il

7kqas0il1#

您在saveChanges函数中缺少Content-Type头设置器指令的基本部分。更改此项:

var xhr = new XMLHttpRequest();
            xhr.open('POST', '/edit_post/' + postId, true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

字符串
对此:

var csrfToken = document.getElementsByName('csrfmiddlewaretoken')[0].value;
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/edit_post/' + postId, true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.setRequestHeader('X-CSRFToken', csrfToken);


它应该可以工作,因为您可能访问views.index页面的所有内容。

相关问题