【问题标题】:Django CORS header ‘Access-Control-Allow-Origin’ missing despite being in Response Headers尽管在响应标头中,但 Django CORS 标头“Access-Control-Allow-Origin”丢失
【发布时间】:2021-03-14 22:51:46
【问题描述】:

我有一个带有 Django 后端 API 和 Angular 前端 SPA 的网页。我已经安装并设置了django-cors-headers==3.5.0 (最后的配置)。尝试从 localhost:4200 从我的 Angular 前端 SPA 加载 .mp3 文件时, 在加载 mp3 文件时,我收到以下错误消息:

跨域请求被阻止:同源策略不允许读取 远程资源在 https://www.aldrune.com/media/session_audio/2020-12-01_-_Session_28.mp3。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。

请注意,同时我可以查看 HTTP 请求,我可以看到与给定的错误消息相反,响应确实有标题:

访问控制允许来源:*

什么给了?如何在我的响应中有标题,但我的浏览器声称它不存在?为什么这只发生在 .mp3 文件中,而我所有来自完全相同的应用程序和 http-server 的媒体和静态文件图像都不受影响?

我知道以前有人问过很多关于 Djanog 和 CORS 的类似问题,但我找不到任何问题,但我非常清楚地看到请求中不存在的标头非常明显。

在我的服务器上的设置下方:

#settings.py
INSTALLED_APPS : list = [
    ...
    'corsheaders',
    ...
]
...
MIDDLEWARE : list = [
    'corsheaders.middleware.CorsMiddleware',
    ...
    'csp.middleware.CSPMiddleware',
]
...
CORS_ALLOW_ALL_ORIGINS = True

CORS_ALLOW_HEADERS = default_headers + (
    "content-disposition",
)


编辑:根据要求,我去邮递员检查了我的标题。正如他所料,直接对 .mp3 文件 (https://www.aldrune.com/media/session_audio/2020-12-01_-_Session_28.mp3.) 的 url 的响应的标头确实包含所述标头。

【问题讨论】:

  • 事实上,据我所知,https://www.aldrune.com/media/session_audio/2020-12-01_-_Session_28.mp3 的响应没有 Access-Control-Allow-Origin 标头。您可以通过尝试curl -i "https://www.aldrune.com/media/session_audio/2020-12-01_-_Session_28.mp3" 或使用 Postman 或其他方式进行确认。 i.stack.imgur.com/389YH.png 的图像没有显示来自 https://www.aldrune.com/media/session_audio/2020-12-01_-_Session_28.mp3 的响应,而是显示来自 https://www.aldrune.com/wiki1/api/sessionaudio/1/28/ 的不同 URL 的响应
  • @sideshowbarker 感谢您的注意,不知何故,我的脑袋搞混了,让 API 调用页面数据来播放音频文件与加载音频文件相同,尽管有两个有 2 个不同的 URL。我检查了邮递员(见上面的编辑),是的,标题不在那里。所以这意味着 mp3 文件的服务可能不会在我的应用程序服务器上运行,而是在我的 http 服务器 apache2 上运行(?我猜这里就是这种情况)。在什么时候...我现在需要以某种方式为 apache 设置它吗?
  • 等等,这太令人困惑了。我的 application server (django) 如何指示应该有 CORS 并将这些设置传输到我的 HTTP 服务器,但是以某种方式来自同一应用程序服务器的设置以设置该 CORS 标头不传输当涉及到可能由所述 HTTP 服务器直接提供的资源时,转移到 HTTP 服务器?
  • 我不确定我是否理解您的最后评论,但听起来您是在暗示 CORS 的要求来自您的 Django 设置。事实并非如此。该要求来自浏览器对同源策略的使用。所以,是的,如果您的媒体文件是从不同的服务器提供的,那么它还需要适当的 CORS 设置。请参阅该服务器软件的文档,无论它是什么。
  • 我的误解是,我认为 Same-Origin-Policy 是由我的 Django 应用程序首先设置的。好吧,想出了如何在 apache 中将 CORS Header 添加到我的媒体文件中,这样就成功了。

标签: django http cors


【解决方案1】:

@Sideshowbarker 和@Kevin Christopher Henry 让我走上了这条正确的道路。失败的请求不是我显示屏幕截图的请求,而是向我的 API 请求在 Django 上运行的网页数据的请求,我确实有一个 CORS 标头。然而,失败的请求是对 .mp3 文件的明确请求。那个是从我的 HTTP 服务器直接路由到我的媒体文件,而不是通过 Django 运行,它会收到一个 CORS 标头。

与我之前的理解相反,浏览器是默认情况下通过其同源策略声明我在本地主机上运行我的前端开发服务器的浏览器,除非服务器说这个来源“localhost”没问题。

因此,鉴于(基于您通常使用 Django 部署的方式)您的文件是通过 HTTP 服务器而不是通过 Django 提供的,您需要配置您的 HTTP 服务器以返回一个允许您的本地主机访问文件的 CORS 标头,在我的例子中是 Apache。

因此,我在我的 apache 配置中添加了一条规则,专门用于我的媒体文件以允许本地主机源 - 无需允许超过必要的内容。 A short resource about this can be found here.

        <Directory /path/to/my/media/directory>
                ... //Other settings for this directory not shown

                SetEnvIf Origin "(http)?(s)?(://)?(www\.)?(localhost:4200|aldrune.com.*)" AccessControlAllowOrigin=$0
                Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
                Header set Access-Control-Allow-Credentials true
        </Directory>

【讨论】:

    猜你喜欢
    • 2012-03-25
    • 2021-08-17
    • 2018-10-20
    • 2019-06-19
    • 1970-01-01
    • 2020-09-21
    • 2021-07-18
    • 2018-09-19
    • 1970-01-01
    相关资源
    最近更新 更多