You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中Access-Control-Allow-Origin缺失的CORS问题求助

Django媒体资源CORS跨域问题解决指南

问题现状

已完成django-cors-headers的安装与基础配置,多数CORS错误已消除,但部署在web.mydomain.com的Flutter Web应用在Firefox中请求媒体资源时仍报错:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.com/media/images/image0_WEEP09I.png. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200

当前配置信息

settings.py关键配置

INSTALLED_APPS = [
    'rest_framework', # dasti ezafe shod
    'rest_framework_simplejwt',
     'corsheaders',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'carat', # dasti ezafe shod
    'data',
    'price',
    'users',
    'marketplace'
]

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

CORS_ORIGIN_WHITELIST = (
    'https://example.com',
    'https://web.example.com',
)

自定义OPTIONS请求处理代码

def options(self, request):
        response = Response()
        response["Access-Control-Allow-Origin"] = "https://example.com"
        response["Access-Control-Allow-Methods"] = "GET, OPTIONS"
        response["Access-Control-Allow-Headers"] = "authorization"
        return response

接口正常响应头示例

HTTP/2 200 OK
Content-Type: application/json
Vary: Accept, origin,Accept-Encoding
Allow: GET, HEAD, OPTIONS
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
Access-Control-Allow-Origin: https://web.example.com
Access-Control-Allow-Credentials: true
Content-Length: 1884
Date: Sat, 03 Feb 2024 22:01:07 GMT
Alt-Svc: h3=":443"; ma=2592000, h3-29=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q043=":443"; ma=2592000, quic=":443"; ma=2592000; v="43,46

问题根源

django-cors-headers仅处理经过Django视图的请求,而生产环境中媒体文件通常由Nginx/Apache等Web服务器直接返回,不会经过Django中间件,因此CORS响应头不会被自动添加到媒体资源的返回结果中。

可行解决方案

方案1:Web服务器层面添加CORS头(推荐生产环境)

以Nginx为例,在媒体资源的location配置块中添加:

location /media/ {
    # 原有媒体资源路径配置
    alias /your/project/media/path/;

    # 强制添加CORS响应头
    add_header Access-Control-Allow-Origin "https://web.mydomain.com" always;
    add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
    add_header Access-Control-Allow-Credentials "true" always;

    # 直接处理OPTIONS预检请求
    if ($request_method = OPTIONS) {
        return 204;
    }
}

注:always参数确保即使返回404/500等非成功状态码时,CORS头仍会被添加;若需允许多个源,可结合Nginx变量实现动态匹配。

方案2:让Django接管媒体资源请求(仅适合开发/小流量场景)

在项目根urls.py中添加媒体资源路由:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # 原有业务路由配置
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

此方法会让媒体请求经过Django中间件,从而触发django-cors-headers的CORS头添加逻辑,但大流量场景下会增加Django服务压力,不推荐生产环境使用。

方案3:调整django-cors-headers配置(针对Django已处理媒体请求的场景)

如果媒体请求确实经过Django处理,可补充以下配置确保CORS规则覆盖媒体路径:

# settings.py
CORS_ALLOWED_ORIGINS = [
    "https://web.mydomain.com",
    "https://example.com",
]
# 让CORS中间件处理媒体路径的请求
CORS_URLS_REGEX = r'^/media/.*$|^/api/.*$'

验证方式

修改配置后,在Firefox中重新请求媒体资源,通过开发者工具查看响应头是否包含Access-Control-Allow-Origin: https://web.mydomain.com,确认CORS错误是否消失。


内容的提问来源于stack exchange,提问作者Sina S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:18:33