简体   繁体   English

Django rest框架ajax表单提交错误403(禁止)

[英]Django rest framework ajax form submit error 403 (forbidden)

When i try to submit my ajaxified form that's working with the DRF API i get in the browser console!当我尝试提交与 DRF API 一起使用的 ajaxified 表单时,我进入了浏览器控制台!

POST http://localhost:8000/api/texts/ 403 (Forbidden) POST http://localhost:8000/api/texts/ 403 (禁止)

here is my html file :这是我的 html 文件:

 <form id="text-form" method="POST" action="">
                   

                            <input type="text" name="title" placeholder="Title" class="form-control mb-3 pb-2"
                                maxlength="200" required id="title">
                            <input type="date" name="deadline" placeholder="Deadline" autocomplete="off"
                                class="form-control mb-3" id="myflatpickr">                                         
                      
                            <textarea name="requirements" cols="40" rows="4"
                                placeholder="requirements"
                                class="form-control col mt-3" maxlength="200" required id="requirements"></textarea>

                    <textarea name="document" cols="40" rows="10"
                        placeholder="document"
                        id="editor" class="form-control" required></textarea>

                <button type="submit">Submit</button>
                </form>

here is my javascript file这是我的 javascript 文件

  $("#text-form").submit(function (event) {
    event.preventDefault();
    $textData = $("#text-form").serialize()
    $.ajax({
      url: "http://localhost:8000/api/texts/",
      method: "POST",
      data: $textData,
      success: function() {
        console.log($textData)
      },
      error: function() {
        console.log("there is an error")

      }
    })

  });

in serializers.py:在 serializers.py 中:


from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
from rest_framework import serializers
from .models import *



class TextSerializer(serializers.ModelSerializer):
     author = serializers.HiddenField(
         default=serializers.CurrentUserDefault()
     )
     class Meta:
         model = Text
         fields = '__all__'

in my views.py file:在我的 views.py 文件中:


class ApiTextList(generics.ListCreateAPIView):

    queryset = Text.objects.all()
    serializer_class = TextSerializer
    permission_classes = [
        permissions.AllowAny
    ]


class ApiTextDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):

    http_method_names = ['get', 'head']
    queryset = Text.objects.all()
    serializer_class = TextSerializer
    permission_classes = [
        permissions.AllowAny
    ]

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

in urls.py在 urls.py 中

from django.urls import path
from . import views


urlpatterns = [

    path('api/texts/', views.ApiTextList.as_view()),
    path('api/texts/<int:pk>/', views.ApiTextDetail.as_view()),
    
    
]

note: when i try to add a text from the interface that drf provides in "localhost:8000/api/texts" i add it normally注意:当我尝试从 drf 在“localhost:8000/api/texts”中提供的界面中添加文本时,我通常会添加它

Now that you told us the content of the details field, it should be easier to fix your problem.既然您已告诉我们详细信息字段的内容,那么解决您的问题应该会更容易。

The Django documentation advises you to get the CSRF token from the cookies. Django 文档建议您从 cookie 中获取 CSRF 令牌。

It even gives you the following function to do that:它甚至为您提供以下功能:

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;
}

And you can then easily adapt your own code by adding those two lines:然后您可以通过添加这两行轻松调整自己的代码:

$("#text-form").submit(function (event) {
    event.preventDefault();
    const csrftoken = getCookie('csrftoken'); // HERE: get the token 
    $textData = $("#text-form").serialize()
    $.ajax({
        url: "http://localhost:8000/api/texts/",
        method: "POST",
        data: $textData,
        headers:{"X-CSRFToken": csrftoken }, // HERE: add it to the request header
        success: function() {
            console.log($textData)
        },
        error: function() {
            console.log("there is an error")
        }
    })
});

If that does not work, please check that you are correctly using Session Authentication .如果这不起作用,请检查您是否正确使用Session Authentication

And to answer your other interrogation, this is normal that your registration view works without the CSRF token: in the DRF, only the views where you need to be authenticated require it.为了回答您的其他询问,您的注册视图在没有 CSRF 令牌的情况下工作是正常的:在 DRF 中,只有您需要进行身份验证的视图需要它。

You are getting Error 403, which means the server understood the request but refuses to authorize it.您收到错误 403,这意味着服务器理解请求但拒绝授权。 You need to add an authorization token while sending an ajax request.您需要在发送 ajax 请求时添加授权令牌。

You can authorize a token on your page using this.您可以使用它在您的页面上授权令牌。

<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>

Then, you have to add the token to your ajax request.然后,您必须将令牌添加到您的 ajax 请求中。

$.ajax({
  url: "http://localhost:8000/api/texts/",
  method: "POST",
  data: $textData,

  csrfmiddlewaretoken: window.CSRF_TOKEN,

  success: function() {
    console.log($textData)
  },
  error: function() {
    console.log("there is an error")

  }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM