fetch 的 headers 选项必须是 headers 实例或键值对普通对象,字符串或数组格式非法;浏览器会自动屏蔽 origin、referer 等敏感头,且自定义头可能触发 cors 预检。

Fetch 的 headers 选项必须是 Headers 实例或普通对象
直接传字符串或数组会报错,比如 headers: "Authorization: Bearer xxx" 或 headers: ["Authorization", "Bearer xxx"] 都不合法。浏览器只接受两种格式:Headers 对象(推荐)或键值对 plain object。
用 plain object 最简单:
fetch("/api/data", {
headers: {
"Authorization": "Bearer abc123",
"X-Client-ID": "web-v2",
"Content-Type": "application/json"
}
});
但注意:plain object 方式下,Content-Type 在 POST 且 body 是 JSON.stringify() 时会被自动设置;若 body 是 FormData,浏览器会自动加 multipart/form-data boundary,手动设反而可能出错。
哪些请求头不能手动覆盖
浏览器会屏蔽或强制重写一部分敏感 header,即使你写了也会被忽略,比如:
-
Connection、Keep-Alive、Proxy-Authenticate、Proxy-Authorization -
Trailer、Transfer-Encoding、Upgrade -
Host(由 URL 自动推导) -
Content-Length(由 body 自动计算)
尝试设置这些字段不会报错,但请求发出后查 DevTools → Network → Headers,会发现它们没出现或被覆盖。尤其注意 Origin 和 Referer —— 它们由浏览器根据当前页面自动注入,无法通过 headers 修改。
需要动态拼接 token 或多环境切换时,用 Headers 实例更可控
当 header 值依赖运行时状态(如从 localStorage 读 token),或需复用/追加逻辑,Headers 构造器比对象字面量更灵活:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
const headers = new Headers({
"X-Client-ID": "web-v2"
});
const token = localStorage.getItem("auth_token");
if (token) {
headers.set("Authorization", `Bearer ${token}`);
}
fetch("/api/profile", { headers });
Headers 实例支持 append()、set()、delete(),适合条件化添加;而且它能自动处理大小写归一化(set("content-type", ...) 会被标准化为 Content-Type),避免手写不一致。
另外,如果后端要求 header 名全小写(极少见),Headers 实例仍会按规范首字母大写,这不是 bug —— HTTP/2 和现代服务端都遵循 RFC 7230,不区分 header 名大小写,但表现形式统一更稳妥。
CORS 场景下,自定义 header 触发预检(OPTIONS)请求
只要你在 headers 中设置了非“CORS-safelisted”字段(比如 X-Request-ID、Authorization),浏览器就会先发一个 OPTIONS 预检请求,确认服务器是否允许该 header。
这意味着后端必须响应正确的 CORS 头:
-
Access-Control-Allow-Headers: X-Request-ID, Authorization(列出你实际用的) -
Access-Control-Allow-Origin: https://yourdomain.com(不能是*,如果带 credentials) - 若用了
credentials: "include",还要加Access-Control-Allow-Credentials: true
开发时常见错误是前端加了 X-Trace-ID,但后端没在 Access-Control-Allow-Headers 里声明,结果预检失败,控制台报错 Request header field x-trace-id is not allowed by Access-Control-Allow-Headers —— 这个错误不是 fetch 写错了,而是后端漏配。
header 看似简单,但跨域、自动注入、预检、大小写处理这几个点串起来,就很容易卡住。最稳妥的做法:先用 plain object 快速验证,再换 Headers 实例做逻辑扩展,每次加新 header 都去 Network 面板确认它真出现在请求里,而不是只信代码写了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










