fetch 不会弹出 HTTP Basic 登录框 (fetch does not prompt for HTTP Basic)
关联:Htpasswd 基础鉴权 · Web 登录鉴权 (Session, Cookie, Bearer, JWT)
发生条件
- 后端给
/api/...加了 HTTP Basic Authentication (HTTP 基础认证):未带凭据时返回401+WWW-Authenticate: Basic ... - 前端用
window.fetch/ axios 等 XHR 调这些接口,没有自己设Authorization - 常见误判:「浏览器第一次 401 会弹原生登录框,之后自动带凭据,所以现有 SPA 不用改」
症状
- 地址栏打开受保护 URL(文档导航)时,确实会弹原生 Basic 框
- 同一源的 SPA 里
fetch('/api/admin/summary')永远 401,页面转圈或报错,没有登录框 - curl 带
-u user:pass正常;浏览器开发者工具里请求没有Authorization
根因
WWW-Authenticate 触发的是文档导航(用户在地址栏进了一个受保护资源)的浏览器 UI。fetch / XHR 被设计成可编程的:401 只是给 JS 的响应,默认不弹窗、不重试、也不记住凭据。credentials: 'include' 也只影响 cookie,不会突然开始发 Basic。
所以「前端一行不改 + 纯 Basic」只对「整页都由浏览器自己请求」的站点成立,对 React admin 这种 fetch('/api/...') 不成立。
处理
不要把 Basic 当成 SPA 的登录方案。可选:
- 服务端登录页发 HttpOnly session cookie(同源
fetch默认带 cookie)。Vite 若只代理/api,登录入口也要挂在/api/...下,cookie 才能种到开发端口。 - 改前端,自己处理 401 / 自己带
Authorization(现有前端不允许改时走 1)。 - 仅本机调试可暂时关掉 API 守门;不要当生产默认。
Basic 仍可留给 curl、脚本、集成测试。
下次怎么认
看到「加了 Basic,前端不用改」+ 代码里是 fetch / axios,就默认会 401。用浏览器直接打开 API URL 能弹框,不能证明 SPA 能登录。
项目证据
rolefit-rs 管理端:源系统 /api/admin/* 是裸的;迁移补门时若只做 Basic,现有 job-admin/frontend 的 useApi.js 会整页失败。落地是 /login + /api/admin/login 会话 cookie,Basic 并行保留。
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Web