no 'access-control-allow-origin' header is present 表明服务端未返回任何cors响应头,浏览器直接拦截;需确认请求是否抵达后端、后端代码是否真正设置了cors头、nginx等代理是否在匹配路径的location块中正确配置add_header。

看报错信息里有没有 No 'Access-Control-Allow-Origin' header is present
这是最常见、也最明确的信号:服务端压根没返回任何 CORS 响应头。浏览器连 Access-Control-Allow-Origin 都没见到,直接拦掉,不给读响应体。
这时候别急着改前端,先确认三点:
- 请求确实发到了后端(查服务端日志或
curl -I直连后端地址),避免被 Nginx / CDN / 负载均衡器静默拦截或重定向 - 后端代码里是否在该路由(或全局中间件)中真正执行了 CORS 头设置逻辑——比如 Express 中漏写了
res.set(...),或 Spring Boot 的@CrossOrigin注解没加到对应 Controller 方法上 - 如果用了反向代理(如 Nginx),
add_header是否写在能匹配到该请求路径的location块内?Nginx 默认不继承父级add_header,写在server级是无效的
报错含 has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header 且后面跟着具体域名
说明服务端返回了 Access-Control-Allow-Origin,但值和当前页面的 Origin 不匹配。典型表现是:
- 后端硬编码设为
Access-Control-Allow-Origin: http://localhost:3000,但你实际是从https://localhost:3000或http://127.0.0.1:3000打开的页面——协议、host、端口必须完全一致 - 用了通配符
*,但前端请求又带了credentials: true(比如withCredentials: true或fetch(..., { credentials: 'include' })),这二者互斥,浏览器会直接拒绝 - 后端做了 Origin 反射(如
res.header('Access-Control-Allow-Origin', req.headers.origin)),但没校验req.headers.origin是否可信,导致安全风险或空值/非法值被原样返回,触发浏览器拒绝
控制台同时出现 OPTIONS 请求失败,且状态码是 4xx 或 5xx
这意味着预检(preflight)没过。浏览器在发真实请求前,先发了个 OPTIONS 请求,而这个请求被后端拒绝了。
常见原因有:
- 后端没注册对
OPTIONS方法的处理逻辑,尤其在自定义路由或 Filter 中,容易忽略该方法 -
Access-Control-Allow-Methods响应头里没包含你实际要用的动词(比如前端用PUT,但后端只写了GET, POST) - 前端带了自定义 Header(如
X-Request-ID),但后端Access-Control-Allow-Headers没声明它,或干脆没返回这个头 - 某些框架(如早期 Spring Boot)默认不处理全局 OPTIONS,需显式配置
WebMvcConfigurer.addCorsMappings并允许所有方法
报错不出现,但响应体为空、status 是 0 或 opaque
这不是标准 CORS 报错,而是你误用了 mode: 'no-cors'。这种模式下请求能发出去,但浏览器强制把响应变成不透明(Response.type === 'opaque'),JS 无法读取 status、headers 或 body。
这种情况多见于:
- 前端想“绕过”CORS,手动加了
mode: 'no-cors',却仍试图解析response.json()或检查response.status - Service Worker 拦截了请求并返回了
no-cors响应,但没做相应适配 - 请求目标是纯资源(如图片、字体),本就不需要 JS 读响应,但开发者误当 API 用
一旦看到 response status 是 0、response.body 为 null、或调用 json() 报 TypeError: Failed to fetch,先搜代码里有没有 no-cors —— 它不是解决方案,只是放弃读响应的开关。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











