在Django Rest Framework中从ModelViewSet调用函数时出现Cors错误

nwo49xxi  于 2023-06-25  发布在  Go
关注(0)|答案(2)|浏览(106)

这个错误很奇怪,我在Django上有一个使用Django Rest Framework的项目,我有一个带有ModelViewSet的应用程序来为我的Race资源创建CRUD端点。
race.py

from ..models.race import Race
from ..serializers.race import RaceSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAuthenticated

class RaceViewSet(ModelViewSet):
    model = Race
    serializer_class = RaceSerializer
    queryset = Race.objects.all()

这是我的应用程序的urls.py

from django.urls import path, include
from rest_framework import routers

from .views.race import RaceViewSet
from .views.test import TestView

router = routers.DefaultRouter()
router.register(r'races', RaceViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('test', TestView.as_view(), name='test'),
]

我正确地设置了所有内容,并且可以使用Postman毫无问题地访问list方法
现在我意识到CORS问题不会发生在Postman中,并安装了'django-cors-headers'来解决我的Angular应用程序上的CORS问题。
settings.py

ALLOWED_HOSTS = []

CORS_ORIGIN_WHITELIST = [
    'http://localhost:4200', # My angular server
]

# Application definition

INSTALLED_APPS = [
    ...
    'rest_framework', 
    'corsheaders',
    ..
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'corsheaders.middleware.CorsMiddleware', # CORS middleware
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

我做了一个测试路径来检查所有东西,在我的Angular 应用程序中,我调用了这个方法
这是测试视图集

from rest_framework.views import APIView
from rest_framework.response import Response
from ..models.race import Race
from ..serializers.race import RaceSerializer

class TestView(APIView):
    def get(self, request): # I copied what the list method should in theory do.
        races = Race.objects.all()
        serializer = RaceSerializer(races, many=True)
        return Response(serializer.data)

home.component.ts

test(): void {
        const url = 'http://127.0.0.1:8000/api/v1/rpg/test'; // This time Im calling the test url
        
        // Send the HTTP POST request
        this.http.get(url).subscribe(
            {
                next: (response) => {
                    // Handle successful sign-up
                    console.log('SUCCESS', response);
                },
                error: (failResponse) => {
                    // Handle sign-up error
                    console.error('Sign-in error:', failResponse);
                },
                complete: () => {
                    console.log('Test completed:');
                }
            }
                
        );
    }

当然,只是为了仔细检查CORS中间件是否真的在工作,我从www.example.com删除了中间件settings.py,并再次尝试测试路由,不出所料,我得到了CORS错误,但再次放置中间件使测试路由工作正常。
但是当尝试访问在我的ModelViewSet上定义的路由时,特别是列表,无论有没有中间件,我都会得到一个CORS错误
home.component.ts

test(): void {
        const url = 'http://127.0.0.1:8000/api/v1/rpg/races'; // Trying to access the races list this time
        
        // Send the HTTP POST request
        this.http.get(url).subscribe(
            {
                next: (response) => {
                    // Handle successful sign-up
                    console.log('SUCCESS', response);
                },
                error: (failResponse) => {
                    // Handle sign-up error
                    console.error('Sign-in error:', failResponse);
                },
                complete: () => {
                    console.log('Test completed:');
                }
            }
                
        );
    }

我在控制台上得到这个错误。
“CORS策略已阻止从源'http://localhost:4200'访问位于'http://127.0.0.1:8000/api/v1/rpg/races'的XMLHttpRequest:请求的资源上不存在'Access-Control-Allow-Origin'标头。”
再次,我相信这条路线工作正常,我尝试了它在 Postman 没有问题,所以我有点在黑暗中在这里,我希望你们能帮助我
编辑
奇怪的是,POST方法似乎工作得很好:/,我仍然在与GET方法作斗争
home.component.ts

test(): void {
        const url = 'http://127.0.0.1:8000/api/v1/rpg/races/'; 
        
        let body = {
            "name": "Lowlander",
            "hp_growth": 1.9,
            "mp_growth": 1.1,
            "str_growth": 1.7,
            "int_growth": 1.2,
            "dex_growth": 1.3,
            "base_hp": 150,
            "base_mp": 100,
            "base_str": 85,
            "base_int": 70,
            "base_dex": 75
        }
        // Send the HTTP POST request
        this.http.post(url,body).subscribe(
            {
                next: (response) => {
                    // Handle successful sign-up
                    console.log('SUCCESS', response);
                },
                error: (failResponse) => {
                    // Handle sign-up error
                    console.error('Sign-in error:', failResponse);
                },
                complete: () => {
                    console.log('Test completed:');
                }
            }
                
        );
    }
rsl1atfo

rsl1atfo1#

试试这个:

CORS_ALLOWED_ORIGINS = [
    'http://localhost:4200'
]
nfg76nw0

nfg76nw02#

我是个白痴,问题是我需要在路由的末尾添加一个/
有了这个url,它就可以正常工作了:')
const url = 'http://127.0.0.1:8000/api/v1/rpg/races/';

相关问题