You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

django-cors-headers 未放行允许来源请求:NextJS前端无法获取Django后端用户数据

解决NextJS对接Django后端时的CORS重定向问题

看起来你遇到的核心问题是301重定向导致的CORS头缺失,而不是django-cors-headers本身没配置对——毕竟你的JWT请求能正常工作,说明基础CORS配置是有效的。我们一步步来拆解:

问题根源分析

错误信息里明确提到Status code: 301,这说明你的请求被Django后端做了重定向(通常是URL末尾斜杠的匹配问题)。当浏览器收到301响应时,会自动跳转到重定向地址,但这个重定向响应的CORS头没有正确设置,所以浏览器触发了跨域错误。

为什么JWT请求没问题?因为你请求的/api/token(POST方法)刚好匹配Django的URL规则(不带末尾斜杠),没有触发重定向,所以CORS头正常返回。

具体解决方案

1. 修正Next.js的重定向配置

你的redirects配置里,destination末尾多了一个斜杠,这会导致路径拼接出错:

async redirects() {
  return [
    {
      source: '/api/:path*',
      // 去掉末尾的斜杠,避免重复拼接导致路径异常
      destination: 'http://localhost:8000/:path*',
      permanent: false, // 先改成临时重定向,避免浏览器缓存301规则
    },
  ]
},

解释:/:path*已经会把/api/users/1里的users/1完整传递过去,再加末尾斜杠会变成users/1/,如果Django的URL规则是不带斜杠的,就会触发301重定向到带斜杠的版本(反之亦然)。

2. 确保Django的CORS配置覆盖重定向场景

虽然你设置了CORS_ALLOW_ALL_ORIGINS = True,但django-cors-headers默认不会在重定向响应里添加CORS头,需要开启额外配置:

# 在settings.py里添加或修改以下配置
CORS_ALLOW_CREDENTIALS = True
# 让重定向响应也能携带CORS头
CORS_PREFLIGHT_MAX_AGE = 86400
# 确保重定向后的请求也被CORS规则覆盖
CORS_REPLACE_HTTPS_REFERER = True

另外,检查Django的APPEND_SLASH设置(默认是True):如果你的URLconf里的路径是带斜杠的,Django会自动把不带斜杠的请求重定向到带斜杠的版本。如果不想用这个特性,可以设置APPEND_SLASH = False,但需要确保所有URL规则和前端请求的URL完全一致。

3. 调整前端请求的URL格式

确保前端请求的URL和Django的URL规则完全匹配:

  • 如果Django的URL是path('users/<int:pk>/', views.UserDetail.as_view())(带斜杠),前端请求就用/api/users/${userId}/(带斜杠)
  • 如果Django的URL是path('users/<int:pk>', views.UserDetail.as_view())(不带斜杠),前端就用/api/users/${userId}(不带斜杠)

4. 验证中间件顺序

确认django-cors-headers的中间件放在CommonMiddleware之前,这样才能在重定向响应生成前添加CORS头:

MIDDLEWARE = [
    # ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    # ...
]

测试验证

修改配置后,重启Next.js和Django服务,然后:

  • 打开浏览器开发者工具的Network面板,确认请求不再返回301状态码
  • 检查响应头里是否包含Access-Control-Allow-Origin字段

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

火山引擎 最新活动