跨域Cookie刷新或离开页面后丢失的成因及解决方法咨询
该现象属于正常行为
Cookie刷新即丢失是浏览器安全规则下的预期表现,核心原因是当前跨域Cookie配置不符合浏览器的Cookie生效、存储规范,不属于平台或框架bug。
核心问题根因
- Domain属性配置违规:你将Cookie的Domain设置为
render.com存在两个问题:一是render.com、*.onrender.com(Render给用户分配的默认服务域名)均在浏览器公共后缀列表(PSL)中,浏览器为防止同平台不同租户的Cookie互相泄露,会直接拒绝向公共后缀域名写入Cookie;二是Render分配的默认API域名一般为xxx.onrender.com,和render.com不属于同根域,Cookie根本无法匹配到你的API接口。 - 跨域凭证配置缺失:如果前端发起请求时未开启携带凭证配置、后端CORS规则未放开凭证允许,浏览器会直接拦截
Set-Cookie响应头,不会将Cookie写入本地存储,自然刷新后就消失。 - 未设置持久化过期时间:如果未给Cookie配置
Max-Age或Expires属性,该Cookie为会话级Cookie,部分浏览器会在页面关闭、跨标签页访问、甚至页面重载时清理这类非持久化Cookie。
修复配置方案
后端Actix-web侧配置
- 修正Cookie属性
删除错误的domain=render.com配置,Domain字段留空即可(浏览器会自动匹配当前API的完整服务域名,安全性最高);保留SameSite=None、Secure=true配置,补充HttpOnly=true防止XSS窃取Cookie,同时设置合理的过期时间将Cookie转为持久化存储。 - 修正CORS规则
CORS配置禁止使用通配符*允许所有源,必须明确填写你部署在Vercel的前端完整域名;开启凭证允许开关,否则浏览器不会接收跨域返回的Cookie。 - 示例代码:
use actix_cors::Cors; use actix_web::{cookie::SameSite, web, App, HttpServer, HttpResponse, cookie::Cookie}; use time::Duration; async fn login() -> HttpResponse { // 构造登录Cookie let session_cookie = Cookie::build("user_session", "your_generated_token") .path("/") // 删掉.domain("render.com")的错误配置,不要手动指定平台根域 .same_site(SameSite::None) .secure(true) .http_only(true) // 设置7天有效期,转为持久化Cookie,避免被浏览器当成会话Cookie清理 .max_age(Duration::days(7)) .finish(); HttpResponse::Ok() .cookie(session_cookie) .json(serde_json::json!({"code": 0, "msg": "login success"})) } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { let cors = Cors::default() // 替换为你自己的Vercel前端域名,禁止写"*" .allowed_origin("https://your-vue3-project.vercel.app") // 允许跨域请求携带Cookie .supports_credentials() .allowed_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"]) .allowed_headers(vec!["Content-Type", "Authorization"]) .max_age(3600); App::new() .wrap(cors) .route("/api/login", web::post().to(login)) }) // Render平台要求服务必须监听10000端口 .bind("0.0.0.0:10000")? .run() .await }
前端Vue3侧配置
所有发往后端的请求必须开启携带凭证配置,否则浏览器不会在跨域请求中携带Cookie,也不会存储接口返回的Set-Cookie内容:
- 如果你用axios作为请求库,全局开启withCredentials配置:
import axios from 'axios' const service = axios.create({ baseURL: 'https://your-api-service.onrender.com', // 跨域请求允许携带Cookie withCredentials: true }) export default service
- 如果你用原生fetch,请求时需要增加
credentials: 'include'配置:
fetch('https://your-api-service.onrender.com/api/login', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({username: 'xxx', password: 'xxx'}) })
校验配置生效
配置完成重新部署后,打开浏览器开发者工具->Application面板->Cookies,选中你的Vercel前端域名,能看到接口下发的user_session Cookie且标记了Secure、SameSite=None属性,即代表配置生效,后续刷新、重开页面Cookie都不会丢失。
内容的提问来源于stack exchange,提问作者Ershetz
相关产品推荐
相关产品推荐

