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

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信号自定义校验规则:

  1. 在你项目中已注册的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)
  1. 在对应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.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:45:40