mode: "cors" 不发起跨域请求,仅声明走cors流程;成功需后端返回access-control-allow-origin响应头,否则浏览器拦截,且带credentials时不能用通配符*。

mode: "cors" 本身不会“发起跨域请求”,它只是声明你“打算跨域”
很多人误以为设了 mode: "cors" 就能绕过同源策略,其实恰恰相反:这个值是告诉浏览器“我要走标准 CORS 流程”,而标准流程的前提是目标服务器必须返回合法的 Access-Control-Allow-Origin 响应头。如果后端没配,请求会直接被浏览器拦截,连网络层都到不了——你看到的往往是 Failed to fetch 或控制台里明确的 CORS 错误信息,比如:Blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present。
所以关键不是前端怎么写 mode,而是前后端是否协同满足以下条件:
-
mode: "cors"是 fetch 的默认值(仅限非 credentials 场景),显式写出来只是增强可读性或避免意外 fallback - 请求 URL 必须是真正跨域的(协议、域名、端口任一不同),否则浏览器根本不会触发 CORS 预检或检查响应头
- 若带凭证(如 cookies),必须同时设
credentials: "include",且服务端响应头需为Access-Control-Allow-Origin: *不再被允许,必须指定确切源
什么时候 fetch 会自动发 OPTIONS 预检?
不是所有 mode: "cors" 请求都会触发预检;只有满足特定条件时,浏览器才在发实际请求前多发一次 OPTIONS。常见触发点包括:
- 使用了自定义请求头,比如
headers: { "X-Trace-ID": "abc" } - 设置了非简单方法(
GET/HEAD/POST以外),如PUT、DELETE -
Content-Type不是application/x-www-form-urlencoded、multipart/form-data或text/plain中的任一值,例如用了application/json
预检失败(比如服务端没处理 OPTIONS 或漏了 Access-Control-Allow-Headers)会导致主请求根本不发出,控制台通常显示 preflight is invalid 或类似提示。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
mode: "no-cors" 看似“绕过”,实则受限极大
有人试过把 mode 改成 "no-cors" 来躲开报错,但这只是让请求发出去而已,结果是得到一个 opaque 类型的响应——你无法读取 response.status、response.headers,甚至 response.json() 会直接抛错。这种模式只适用于你完全不需要响应内容的场景(比如埋点上报),对绝大多数 API 调用毫无意义。
简言之:mode: "no-cors" ≠ 跨域成功,它等于“发出去,但不许看结果”。
调试时最容易忽略的三个点
实际开发中,很多问题卡在细节上,而不是概念不清:
- 本地开发服务器(如 Vite、Webpack Dev Server)开了代理,你以为是跨域,其实请求根本没出浏览器——代理把地址转成了同源,
mode: "cors"形同虚设 - 后端设置了
Access-Control-Allow-Origin,但值是动态拼接的(比如从Origin请求头复制),却忘了处理空值或非法协议(如file://),导致匹配失败 - 服务端响应头用了
Access-Control-Allow-Origin: https://example.com,但前端页面是从http://localhost:3000打开的,协议/端口不匹配,照样被拦
真要验证是否走通 CORS,最可靠的方式是打开浏览器 Network 面板,找那个请求,看 Headers 标签页里 Response Headers 是否包含正确的 Access-Control-Allow-Origin,并且 Preview/Response 标签页能正常显示数据。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










