Search code examples
djangoangulardjango-rest-frameworkcorsdjango-cors-headers

API request from Angular App to Django REST API - blocked by CORS


I have a working Angular app that gets data from a Django REST api. The api requests are successful when I make requests to some endpoints but fail due to being blocked by CORS on other endpoints.

My CORS configuration in django app:

Whitelist:

CORS_ORIGIN_WHITELIST = (
    'http://localhost:4200', # my angular app
    'http://localhost:8080',
)

Middleware:

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
]

Installed Apps:

INSTALLED_APPS = [
    ...
    'corsheaders',
]

When I make this get request in my angular app, it succeeds and i get back the result i expect

Angular request:

public getProviders(searchParams: ProviderSearchParams): Observable<ProviderSearchResult> {
    const p = this.serializeParams(searchParams, new HttpParams());
    return this.http.get<any>(`${this.base_url}/providers/`, {params: p})
      .pipe(map(this.deserializeAs(ProviderSearchResult)));
}

Django Endpoint

# urls
path('', views.ProviderList.as_view(), name="api_provider_list"),

# views
class ProviderList(generics.ListAPIView):
    """
    View all providers.
    """
    queryset = Provider.objects.filter(is_accepted=True)    
    filter_backends = [DjangoFilterBackend,
                       filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['name', 'branches__city', 'branches__area']
    search_fields = ['name', 'branches__name',
                     'branches__city', 'branches__area']
    ordering_fields = ['name', 'created_date']
    pagination_class = PageNumberPagination

    def get_serializer_class(self):
        if self.request.user.is_staff:
            return AdminProviderSerializer
        return PublicProviderSerializer

However, it seems to fail with error blocked by CORS when i make a request to a generics.RetrieveUpdateDestroyAPIView. Here is an example:

Angular request:

public getProviderBySlug = (slug: string): Observable<Provider> =>
    this.http.get<any>(`${this.base_url}/providers/${slug}`)
      .pipe(map(this.deserializeAs(Provider)))

Django Endpoint

# urls
path('<slug:slug>/', views.ProviderDetail.as_view(), name="api_provider_details"),

# views
class ProviderDetail(generics.RetrieveAPIView):
    """
    Returns a single provider
    """
    queryset = Provider.objects.all()
    serializer_class = PublicProviderSerializer

    def get_object(self):
        return Provider.objects.get(slug=self.kwargs.get('slug', None))

Seems like requests to generics.RetrieveUpdateDestroyAPIView and generics.RetrieveAPIView are causing this CORS error

Error

Access to XMLHttpRequest at 'http://localhost:8000/api/providers/icc' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Solution

  • Please add /

    Like that

    this.http.get<any>(`${this.base_url}/providers/${slug}/`) <---- '/' is there