Django配置CORS如何允许任意端口的localhost来源访问
问题原因
CORS_ALLOWED_ORIGINS 采用完整字符串精确匹配逻辑,不支持端口通配符,因此仅配置"http://localhost"无法匹配带随机端口的Flutter开发服务来源。django-cors-headers本身提供了两种不需要开启CORS_ORIGIN_ALLOW_ALL = True的实现方式,均可实现仅放行localhost任意端口的开发请求,不会放开所有外部来源。
方案1:使用内置正则匹配配置(最简便)
直接在Django的settings.py中添加CORS_ALLOWED_ORIGIN_REGEXES配置项,通过正则规则匹配允许的来源即可,不需要额外编写信号逻辑:
# 原有精确匹配配置可保留,生产环境用 CORS_ALLOWED_ORIGINS = [ # 你的生产环境正式来源地址 ] # 开发环境追加正则规则,匹配本地任意端口 CORS_ALLOWED_ORIGIN_REGEXES = [ r"^http://localhost:\d+$", r"^http://127\.0\.0\.1:\d+$", ]
配置说明:
^匹配字符串开头,$匹配字符串结尾,避免非预期的域名拼接绕过\d+匹配1位及以上数字,覆盖所有合法端口号- 同时覆盖
localhost和127.0.0.1两个本地环回地址,避免Flutter不同启动模式下访问地址差异导致的跨域问题
方案2:自定义信号校验(适合复杂判断场景)
如果你需要叠加更复杂的跨域判断逻辑(比如仅放行特定路径、特定请求头的本地请求),可以使用django-cors-headers提供的check_request_enabled信号自定义校验规则:
- 在你项目中已注册的app下新建
signals.py,编写校验逻辑:
from urllib.parse import urlparse from corsheaders.signals import check_request_enabled def allow_localhost_dev(sender, request, **kwargs): origin = request.META.get("HTTP_ORIGIN", "") if not origin: return False parsed_origin = urlparse(origin) # 仅放行http协议下本地环回地址的任意端口请求 if ( parsed_origin.scheme == "http" and parsed_origin.hostname in ("localhost", "127.0.0.1") ): return True return False check_request_enabled.connect(allow_localhost_dev)
- 在对应app的
apps.py的ready方法中导入信号模块,确保逻辑生效:
from django.apps import AppConfig class YourAppConfig(AppConfig): default_auto_field = "django.db.models.BigAutoField" name = "your_app_name" # 替换为你的实际app名 def ready(self): import your_app_name.signals # 替换为你实际的signals模块路径
注意事项
- 以上宽松匹配规则 仅建议在开发环境使用,部署到生产环境时请移除正则/自定义信号逻辑,仅保留
CORS_ALLOWED_ORIGINS中的精确正式域名配置,避免安全风险。 - 两种方案的优先级均高于默认的全来源开关,不需要开启
CORS_ORIGIN_ALLOW_ALL = True,非本地来源的跨域请求依然会被正常拦截。
内容的提问来源于stack exchange,提问作者Daniel N.
相关产品推荐
相关产品推荐

