文件上传跨域 cookie 丢失导致鉴权失败,本质是凭据传递链断裂:前端需显式启用 credentials: 'include' 或 withcredentials: true,后端必须返回 access-control-allow-credentials: true、精确匹配的 access-control-allow-origin 及合规 set-cookie 头,且上传接口须完整参与 cors 配置。

文件上传时因跨域 Cookie 丢失导致鉴权失败,本质是浏览器未将凭证(Cookie)随请求发出,后端无法识别用户身份。这不是上传本身的问题,而是跨域凭据传递链断裂——从登录种 Cookie、到上传带 Cookie、再到服务端正确响应,任一环节出错都会触发 401 或 403。
前端请求必须显式启用凭据模式
无论用 fetch、XMLHttpRequest 还是封装库(如 Axios、uni-app 的 uni.uploadFile),都需主动声明携带 Cookie:
-
fetch:每个上传请求必须加
credentials: 'include',不能省略或设为'same-origin' -
XMLHttpRequest:在
xhr.open()后、xhr.send()前设置xhr.withCredentials = true -
uni.uploadFile:需传入
withCredentials: true(H5 端有效,App 端需额外处理) -
Axios:全局配置或单次请求中设
withCredentials: true,且不可与credentials: 'include'混用
后端响应头必须严格匹配并许可凭据
仅前端开启凭据不够,服务端必须同步满足三项硬性条件:
-
Access-Control-Allow-Credentials: true —— 必须返回,且值为字符串
"true"(不是布尔值) -
Access-Control-Allow-Origin —— 不能是
*,必须精确等于前端来源(如https://your-h5.com),协议、域名、端口全匹配 -
Set-Cookie 头合规 —— 登录接口返回的 Cookie 必须含
SameSite=None; Secure(HTTPS 环境),开发环境若用 HTTP,则改用SameSite=Lax并去掉Secure
注意 file:// 协议和本地调试陷阱
H5 在某些调试场景(如直接双击 HTML 文件、或某些 WebView 加载本地资源)会走 file:// 协议。此时浏览器视其为“无源”(opaque origin),withCredentials 会被忽略,Cookie 完全不发送。解决方法:
- 开发阶段务必用本地服务器启动(如
http-server、vite preview、npm run serve),确保协议为http://或https:// - 避免在 Chrome 中用
--disable-web-security调试,该方式绕过全部安全机制,行为与生产环境严重脱节 - 检查 Network 面板中上传请求的 Request Headers,确认有
Cookie:字段;若没有,说明凭据未启用或被浏览器拦截
上传接口本身也要参与 CORS 全流程
很多开发者只给登录、API 接口配 CORS,却漏掉文件上传地址(如 /api/upload)。只要该 URL 是跨域的,就必须同样返回上述三个关键响应头。尤其注意:
- 如果上传走的是表单提交(
<form method="POST" enctype="multipart/form-data"></form>),浏览器仍会自动携带同域 Cookie,但前提是页面与目标域满足同源策略或已通过 CORS 显式许可 - 若后端用 Nginx 做反向代理,需在对应
location /api/upload块中重复添加 CORS 头,不能只配在主 API 路由下 - 预检请求(OPTIONS)必须成功返回 204,否则上传请求根本不会发出











