如何在React与Django之间共享单个会话?
解决React + Django跨域会话不保持的问题
这个问题我之前踩过一模一样的坑!核心原因是跨域请求时axios默认不会携带Cookie,而Django的会话是靠sessionid Cookie来标识用户的——React每次发请求都不带这个Cookie,服务器就会认为是新用户,每次创建新会话,自然存不住数据。Postman会自动帮你处理Cookie的携带,所以测试正常。
下面是一步步的解决方案:
1. 配置Django允许跨域携带Cookie
首先确保你已经安装了django-cors-headers(如果没装,先跑pip install django-cors-headers),然后修改settings.py:
- 在
INSTALLED_APPS里添加:INSTALLED_APPS = [ # ... 其他已有的app 'corsheaders', ] - 在
MIDDLEWARE里添加CorsMiddleware(注意要放在CommonMiddleware前面):MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... 其他中间件 ] - 开启跨域携带凭证,并指定允许的React域名(改成你的React实际端口,比如3000):
CORS_ALLOW_CREDENTIALS = True CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", # 如果是127.0.0.1访问的话也加上: "http://127.0.0.1:3000", ]
2. 修改React的axios请求,让它携带Cookie
你有两种方式配置:
方式一:全局配置axios(推荐)
在React项目的入口文件(比如src/index.js)里添加一行:
import axios from 'axios'; axios.defaults.withCredentials = true; // 全局开启携带Cookie
这样所有axios请求都会自动带Cookie,不用每次单独设置。
方式二:单独给这个请求配置
如果只想让这个特定请求带Cookie,修改你的请求代码:
const data = await axios.post( "http://127.0.0.1:8000/api/urls/", qs.stringify({ long: long_url, subpart: subpart }), { withCredentials: true } // 新增这个配置项 );
3. 优化Django视图的会话操作(可选但推荐)
当你修改会话里的可变对象(比如列表)时,Django有时候检测不到会话的变化,导致不会自动保存。所以建议在视图里手动标记会话已修改:
@api_view(['POST']) def users_urls(request): # 可以加一行打印调试,确认会话ID是否一致 print("当前会话ID:", request.session.session_key) if request.method == 'POST': long_url = request.POST.get('long') subpart = request.POST.get('subpart') if 'users_urls' in request.session: request.session['users_urls'].append(subpart) else: request.session['users_urls'] = [subpart] # 手动标记会话已修改,确保Django保存会话 request.session.modified = True return Response(short_url)
做完这些配置后,你再测试一下:React每次发请求都会携带sessionid Cookie,Django就能识别同一个会话,你的users_urls列表就能正常追加数据了!
内容的提问来源于stack exchange,提问作者Flakee
相关产品推荐
相关产品推荐

