Ad

Fetch Request To Django Server CORS Blocks Only One View

- 1 answer

I have a react frontend running on localhost port 8080 and a django backend on port 8000. I build an API that I call through javascript fetch requests. The django backend has cors-headers installed and set to CORS_ORIGIN_ALLOW_ALL=True. The fetch does work for all endpoints in the API, except a new endpoint called metrics I just added. Once I call this view on a GET request I recieve the following error:

Access to fetch at 'http://localhost:8000/api/v1/metrics/' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

I use the same fetch method to call all API endpoints:

return fetch(url, {
    method: 'GET',
    mode: 'cors',
    cache: 'no-cache',
    credentials: 'same-origin',
    headers: {
      'Authorization': 'Token ' + token
    },
    redirect: 'follow',
    referrer: 'no-referrer',
  })

Also the call does work through postman, however not from the React-App. I suppose the error is originated in the preflight OPTIONS response the django server gives, however I fail to see how the response is different from other endpoints. The definition of the view is:

class ListMetrics(generics.ListCreateAPIView):
  '''Lists and creates new Metrics.'''
  queryset = models.Metric.objects.all()
  serializer_class = serializers.MetricSerializer

(Authorization is enabled in the django settings by default and does work with the same token for all other endpoints).

Update

Adding the authorization header explicitly in the django config does yield the same error:

CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)

Update 2

Here are urls.py and views.py for completeness:

urls.py from the Django App (only relevant parts):

urlpatterns = [
  # tags endpoint
  path("tags/", views.ListTags.as_view(), name="list-user-tags"),

  # ... some other endpoints  

  # metrics endpoint
  path("metrics/", views.ListMetrics.as_view(), name="list-global-metrics"),

  # ... some authentication endpoints
]

Views for the two endpoints described above:

class ListTags(generics.ListCreateAPIView):
  queryset = models.Tag.objects.all()
  serializer_class = serializers.TagSerializer

  def get_queryset(self):
    return perm.filterModelCreator(models.Tag, self.request.user)

class ListMetrics(generics.ListCreateAPIView):
  '''Lists and creates new Metrics.'''
  queryset = models.Metric.objects.all()
  serializer_class = serializers.MetricSerializer

The tags view has a get_queryset function to filter only tags created by the user.

Uodate 3

Sending the same request through jquery ajax instead of fetch leads to the same error:

Access to XMLHttpRequest at 'http://localhost:8000/api/v1/metrics/?_=1565265240772' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

Thank you!

Ad

Answer

Okay, I isolated the problem. It appears that the integrated adblock of the browser blocked the CORS request. However, I don't know why this only happened to this one request...

Anyway, if I disable the protection features for the site the request works as it should.

Ad
source: stackoverflow.com
Ad