对 Django 服务器 CORS 的获取请求仅阻止一个视图

Posted

技术标签:

【中文标题】对 Django 服务器 CORS 的获取请求仅阻止一个视图【英文标题】:Fetch Request to Django Server CORS blocks only one view 【发布时间】:2019-12-16 01:16:48 【问题描述】:

我有一个在 localhost 端口 8080 上运行的 react 前端和一个在端口 8000 上运行的 django 后端。我构建了一个通过 javascript 获取请求调用的 API。 django 后端安装了cors-headers 并设置为CORS_ORIGIN_ALLOW_ALL=True。 除了我刚刚添加的名为metrics 的新端点之外,该获取确实适用于 API 中的所有端点。 一旦我在 GET 请求上调用此视图,我就会收到以下错误:

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.

我使用相同的 fetch 方法来调用所有 API 端点:

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

此外,调用确实通过邮递员工作,但不是来自 React-App。我想该错误源于 django 服务器提供的预检 OPTIONS 响应,但是我看不到响应与其他端点有何不同。视图的定义是:

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

(默认情况下,授权在 django 设置中启用,并且对所有其他端点使用相同的令牌)。

更新

在 django 配置中显式添加 authorization 标头确实会产生相同的错误:

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

更新 2

为了完整起见,这里是 urls.py 和 views.py:

来自 Django 应用程序的 urls.py(仅相关部分):

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
]

上述两个端点的视图:

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

标签视图有一个get_queryset 函数来过滤用户创建的标签。

Uodate 3

通过 jquery ajax 而不是 fetch 发送相同的请求会导致相同的错误:

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.

谢谢!

【问题讨论】:

你在 INSTALLED_APPS 中添加了 corsheaders 吗? 是的。我在 installedApps 中有 corsheaders 并添加了中间件。奇怪的是,cors 实际上适用于我拥有的所有其他视图。只是不适合这个。但是我看不出与其他观点有什么不同。 我找不到您的确切问题,但请您尝试在 settings.py 中设置 CORS_ORIGIN_ALLOW_ALL = True 已经有这个设置 好的,我再检查一下,很快就会更新 【参考方案1】:

好的,我隔离了问题。似乎浏览器的集成广告块阻止了 CORS 请求。但是,我不知道为什么这只发生在这一个请求上......

无论如何,如果我禁用网站的保护功能,请求就会正常工作。

【讨论】:

以上是关于对 Django 服务器 CORS 的获取请求仅阻止一个视图的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中使用 Axios 和 CORS 获取 POST 请求的错误请求并做出反应

如何使用 Angular 7 在 django1.1 中启用 cors?

使用 Ajax/Javascript/Django 的 CORS 请求

来自 Django 服务器的 reactjs 请求时出错(403 错误/CORS)

浏览器向 django 发出 CORS 请求的 OPTIONS 请求,但没有 POST

Django CORS 请求外部重定向不允许