GET请求可正常携带Cookie,Axios发送PUT/POST请求时Cookie缺失如何解决?
解决方案
- 第一步:补全后端CORS配置,处理预检请求
你当前的CORS配置缺少允许的请求头、请求方法声明,非简单请求(带自定义Content-Type的PUT/POST)会先发送OPTIONS预检请求,后端需要正确响应预检才能触发真实请求携带Cookie。修改cors配置如下:
const corsOptions = { origin: '你的前端完整域名,比如http://localhost:3000', // 绝对不能用*,必须和你前端请求的origin完全一致 credentials: true, allowedHeaders: ['Authorization', 'Content-Type', 'Cookie'], // 允许前端发送的头字段 methods: ['GET', 'PUT', 'POST', 'OPTIONS', 'DELETE'] // 允许的请求方法 } app.use(cors(corsOptions)) // 显式响应所有OPTIONS请求,避免其他中间件拦截 app.options('*', cors(corsOptions))
- 第二步:修正Cookie的设置属性
跨域场景下后端设置Cookie时必须添加以下属性,否则浏览器会拦截Cookie不会自动携带:
// Express设置Cookie示例 res.cookie('key', 'cookie值', { sameSite: 'none', // 跨域必须设为none secure: true, // sameSite为none时必须同时开启secure,要求前后端都使用HTTPS协议 domain: '.你的根域名.com', // 确保同时覆盖前端和后端的域名,比如前端是app.xxx.com,后端是api.xxx.com,就填.xxx.com path: '/', httpOnly: true // 按需开启,不影响携带 })
如果是本地开发用HTTP协议的场景,把sameSite改为'lax',secure设为false,同时前后端都使用localhost域名(不要用127.0.0.1和localhost混用)。
- 第三步:修正Axios请求代码
不需要手动对data做JSON.stringify处理,Axios会自动根据Content-Type转换请求体:
var url = 'APIurl/test' var data = { test: test } var config = { headers: { 'Authorization': "Bearer " + myPersonnalToken, 'Content-Type': 'application/json', }, withCredentials: true, } // 直接传data对象即可,不用JSON.stringify axios.put(url, data, config) .then(res => { console.log(res) }) .catch(err => { console.log(err) })
如果是用axios.create创建的全局实例,需要在实例初始化时就配置withCredentials: true,避免单个请求配置不生效。
- 第四步:排查预检请求是否正常
打开浏览器开发者工具的Network面板,找到对应的OPTIONS预检请求,确认响应头中返回了以下字段:Access-Control-Allow-Origin:值为你的前端域名,不是*Access-Control-Allow-Credentials:值为trueAccess-Control-Allow-Headers:包含你请求中带的Authorization、Content-Type字段Access-Control-Allow-Methods:包含PUT/POST方法
只要预检请求正常通过,浏览器就会自动携带符合属性要求的Cookie发送真实的PUT/POST请求。
内容的提问来源于stack exchange,提问作者Hugo GB
相关产品推荐
相关产品推荐

